Update support for Inventec d7032q28b/d7054q28b

This commit is contained in:
robertyu
2018-11-15 21:47:55 -08:00
parent a5ec39317e
commit 2d05351193
70 changed files with 37052 additions and 1717 deletions

View File

@@ -1 +1 @@
!include $ONL_TEMPLATES/no-arch-vendor-modules.yml ARCH=amd64 VENDOR=inventec
!include $ONL_TEMPLATES/arch-vendor-modules.yml ARCH=amd64 VENDOR=inventec KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"

View File

@@ -0,0 +1 @@
lib

View File

@@ -0,0 +1,6 @@
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
KMODULES := src
VENDOR := inventec
BASENAME := common
ARCH := x86_64
include $(ONL)/make/kmodule.mk

View File

@@ -0,0 +1 @@
obj-m += inv_eeprom.o

View File

@@ -0,0 +1,193 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x53, I2C_CLIENT_END };
/* Size of EEPROM in bytes */
#define EEPROM_SIZE 256
#define SLICE_BITS (6)
#define SLICE_SIZE (1 << SLICE_BITS)
#define SLICE_NUM (EEPROM_SIZE/SLICE_SIZE)
/* Each client has this additional data */
struct eeprom_data {
struct mutex update_lock;
u8 valid; /* bitfield, bit!=0 if slice is valid */
unsigned long last_updated[SLICE_NUM]; /* In jiffies, 8 slices */
u8 data[EEPROM_SIZE]; /* Register values */
};
static void inv_eeprom_update_client(struct i2c_client *client, u8 slice)
{
struct eeprom_data *data = i2c_get_clientdata(client);
int i, j;
int ret;
int addr;
mutex_lock(&data->update_lock);
if (!(data->valid & (1 << slice)) ||
time_after(jiffies, data->last_updated[slice] + 300 * HZ)) {
dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
addr = slice << SLICE_BITS;
ret = i2c_smbus_write_byte_data(client, ((u8)addr >> 8) & 0xFF, (u8)addr & 0xFF);
/* select the eeprom address */
if (ret < 0) {
dev_err(&client->dev, "address set failed\n");
goto exit;
}
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE)) {
goto exit;
}
for (i = slice << SLICE_BITS; i < (slice + 1) << SLICE_BITS; i+= SLICE_SIZE) {
for (j = i; j < (i+SLICE_SIZE); j++) {
int res;
res = i2c_smbus_read_byte(client);
if (res < 0) {
goto exit;
}
data->data[j] = res & 0xFF;
}
}
data->last_updated[slice] = jiffies;
data->valid |= (1 << slice);
}
exit:
mutex_unlock(&data->update_lock);
}
static ssize_t inv_eeprom_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
struct eeprom_data *data = i2c_get_clientdata(client);
u8 slice;
if (off > EEPROM_SIZE) {
return 0;
}
if (off + count > EEPROM_SIZE) {
count = EEPROM_SIZE - off;
}
if (count == 0) {
return 0;
}
/* Only refresh slices which contain requested bytes */
for (slice = off >> SLICE_BITS; slice <= (off + count - 1) >> SLICE_BITS; slice++) {
inv_eeprom_update_client(client, slice);
}
memcpy(buf, &data->data[off], count);
return count;
}
static struct bin_attribute inv_eeprom_attr = {
.attr = {
.name = "eeprom",
.mode = S_IRUGO,
},
.size = EEPROM_SIZE,
.read = inv_eeprom_read,
};
/* Return 0 if detection is successful, -ENODEV otherwise */
static int inv_eeprom_detect(struct i2c_client *client, struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
/* EDID EEPROMs are often 24C00 EEPROMs, which answer to all
addresses 0x50-0x57, but we only care about 0x50. So decline
attaching to addresses >= 0x51 on DDC buses */
if (!(adapter->class & I2C_CLASS_SPD) && client->addr != 0x53) {
return -ENODEV;
}
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
return -ENODEV;
}
strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
return 0;
}
static int inv_eeprom_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct eeprom_data *data;
int err;
if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
memset(data->data, 0xff, EEPROM_SIZE);
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* create the sysfs eeprom file */
err = sysfs_create_bin_file(&client->dev.kobj, &inv_eeprom_attr);
if (err) {
goto exit_kfree;
}
return 0;
exit_kfree:
kfree(data);
exit:
return err;
}
static int inv_eeprom_remove(struct i2c_client *client)
{
sysfs_remove_bin_file(&client->dev.kobj, &inv_eeprom_attr);
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id inv_eeprom_id[] = {
{ "inv_eeprom", 0 },
{ }
};
static struct i2c_driver inv_eeprom_driver = {
.driver = {
.name = "inv_eeprom",
},
.probe = inv_eeprom_probe,
.remove = inv_eeprom_remove,
.id_table = inv_eeprom_id,
.class = I2C_CLASS_DDC | I2C_CLASS_SPD,
.detect = inv_eeprom_detect,
.address_list = normal_i2c,
};
module_i2c_driver(inv_eeprom_driver);
MODULE_AUTHOR("Inventec");
MODULE_DESCRIPTION("Inventec Switch Mother Board EEPROM driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,2 @@
*x86*64*inventec*d7032q28b*.mk
onlpdump.mk

View File

@@ -1,5 +1,5 @@
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
KMODULES := $(wildcard *.c)
KMODULES := src
VENDOR := inventec
BASENAME := x86-64-inventec-d7032q28b
ARCH := x86_64

View File

@@ -0,0 +1,9 @@
#obj-m += gpio-ich.o
obj-m += inv_platform.o
obj-m += inv_cpld.o
obj-m += inv_psoc.o
obj-m += swps.o
swps-objs := inv_swps.o io_expander.o transceiver.o inv_mux.o
obj-m += vpd.o
vpd-objs := inv_vpd.o onie_tlvinfo.o
obj-m += inv_pthread.o

View File

@@ -0,0 +1,548 @@
/*
* Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
*
* Copyright (C) 2010 Extreme Engineering Solutions.
*
* 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.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mfd/lpc_ich.h>
#define DRV_NAME "gpio_ich"
/*
* GPIO register offsets in GPIO I/O space.
* Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
* LVLx registers. Logic in the read/write functions takes a register and
* an absolute bit number and determines the proper register offset and bit
* number in that register. For example, to read the value of GPIO bit 50
* the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)],
* bit 18 (50%32).
*/
enum GPIO_REG {
GPIO_USE_SEL = 0,
GPIO_IO_SEL,
GPIO_LVL,
GPO_BLINK
};
static const u8 ichx_regs[4][3] = {
{0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */
{0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */
{0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
{0x18, 0x18, 0x18}, /* BLINK offset */
};
static const u8 ichx_reglen[3] = {
0x30, 0x10, 0x10,
};
static const u8 avoton_regs[4][3] = {
{0x00, 0x80, 0x00},
{0x04, 0x84, 0x00},
{0x08, 0x88, 0x00},
};
static const u8 avoton_reglen[3] = {
0x10, 0x10, 0x00,
};
#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
struct ichx_desc {
/* Max GPIO pins the chipset can have */
uint ngpio;
/* chipset registers */
const u8 (*regs)[3];
const u8 *reglen;
/* GPO_BLINK is available on this chipset */
bool have_blink;
/* Whether the chipset has GPIO in GPE0_STS in the PM IO region */
bool uses_gpe0;
/* USE_SEL is bogus on some chipsets, eg 3100 */
u32 use_sel_ignore[3];
/* Some chipsets have quirks, let these use their own request/get */
int (*request)(struct gpio_chip *chip, unsigned offset);
int (*get)(struct gpio_chip *chip, unsigned offset);
/*
* Some chipsets don't let reading output values on GPIO_LVL register
* this option allows driver caching written output values
*/
bool use_outlvl_cache;
};
static struct {
spinlock_t lock;
struct platform_device *dev;
struct gpio_chip chip;
struct resource *gpio_base; /* GPIO IO base */
struct resource *pm_base; /* Power Mangagment IO base */
struct ichx_desc *desc; /* Pointer to chipset-specific description */
u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
u8 use_gpio; /* Which GPIO groups are usable */
int outlvl_cache[3]; /* cached output values */
} ichx_priv;
static int modparam_gpiobase = -1; /* dynamic */
module_param_named(gpiobase, modparam_gpiobase, int, 0444);
MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, "
"which is the default.");
static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
{
unsigned long flags;
u32 data, tmp;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
int ret = 0;
spin_lock_irqsave(&ichx_priv.lock, flags);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr];
else
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (val)
data |= 1 << bit;
else
data &= ~(1 << bit);
ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
ichx_priv.outlvl_cache[reg_nr] = data;
tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (verify && data != tmp)
ret = -EPERM;
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return ret;
}
static int ichx_read_bit(int reg, unsigned nr)
{
unsigned long flags;
u32 data;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
spin_lock_irqsave(&ichx_priv.lock, flags);
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr] | data;
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return data & (1 << bit) ? 1 : 0;
}
static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
{
return !!(ichx_priv.use_gpio & (1 << (nr / 32)));
}
static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
{
/*
* Try setting pin as an input and verify it worked since many pins
* are output-only.
*/
if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1))
return -EINVAL;
return 0;
}
static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
int val)
{
/* Disable blink hardware which is available for GPIOs from 0 to 31. */
if (nr < 32 && ichx_priv.desc->have_blink)
ichx_write_bit(GPO_BLINK, nr, 0, 0);
/* Set GPIO output value. */
ichx_write_bit(GPIO_LVL, nr, val, 0);
/*
* Try setting pin as an output and verify it worked since many pins
* are input-only.
*/
if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1))
return -EINVAL;
return 0;
}
static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
{
return ichx_read_bit(GPIO_LVL, nr);
}
static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
{
unsigned long flags;
u32 data;
/*
* GPI 0 - 15 need to be read from the power management registers on
* a ICH6/3100 bridge.
*/
if (nr < 16) {
if (!ichx_priv.pm_base)
return -ENXIO;
spin_lock_irqsave(&ichx_priv.lock, flags);
/* GPI 0 - 15 are latched, write 1 to clear*/
ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base);
data = ICHX_READ(0, ichx_priv.pm_base);
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return (data >> 16) & (1 << nr) ? 1 : 0;
} else {
return ichx_gpio_get(chip, nr);
}
}
static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
{
if (!ichx_gpio_check_available(chip, nr))
return -ENXIO;
/*
* Note we assume the BIOS properly set a bridge's USE value. Some
* chips (eg Intel 3100) have bogus USE values though, so first see if
* the chipset's USE value can be trusted for this specific bit.
* If it can't be trusted, assume that the pin can be used as a GPIO.
*/
if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
return 0;
return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
}
static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr)
{
/*
* Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100
* bridge as they are controlled by USE register bits 0 and 1. See
* "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for
* additional info.
*/
if (nr == 16 || nr == 17)
nr -= 16;
return ichx_gpio_request(chip, nr);
}
static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
{
ichx_write_bit(GPIO_LVL, nr, val, 0);
}
static void ichx_gpiolib_setup(struct gpio_chip *chip)
{
chip->owner = THIS_MODULE;
chip->label = DRV_NAME;
chip->dev = &ichx_priv.dev->dev;
/* Allow chip-specific overrides of request()/get() */
chip->request = ichx_priv.desc->request ?
ichx_priv.desc->request : ichx_gpio_request;
chip->get = ichx_priv.desc->get ?
ichx_priv.desc->get : ichx_gpio_get;
chip->set = ichx_gpio_set;
chip->direction_input = ichx_gpio_direction_input;
chip->direction_output = ichx_gpio_direction_output;
chip->base = modparam_gpiobase;
chip->ngpio = ichx_priv.desc->ngpio;
chip->can_sleep = false;
chip->dbg_show = NULL;
}
/* ICH6-based, 631xesb-based */
static struct ichx_desc ich6_desc = {
/* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
.request = ich6_gpio_request,
.get = ich6_gpio_get,
/* GPIO 0-15 are read in the GPE0_STS PM register */
.uses_gpe0 = true,
.ngpio = 50,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Intel 3100 */
static struct ichx_desc i3100_desc = {
/*
* Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on
* the Intel 3100. See "Table 712. GPIO Summary Table" of 3100
* Datasheet for more info.
*/
.use_sel_ignore = {0x00130000, 0x00010000, 0x0},
/* The 3100 needs fixups for GPIO 0 - 17 */
.request = ich6_gpio_request,
.get = ich6_gpio_get,
/* GPIO 0-15 are read in the GPE0_STS PM register */
.uses_gpe0 = true,
.ngpio = 50,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH7 and ICH8-based */
static struct ichx_desc ich7_desc = {
.ngpio = 50,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH9-based */
static struct ichx_desc ich9_desc = {
.ngpio = 61,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH10-based - Consumer/corporate versions have different amount of GPIO */
static struct ichx_desc ich10_cons_desc = {
.ngpio = 61,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
static struct ichx_desc ich10_corp_desc = {
.ngpio = 72,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Intel 5 series, 6 series, 3400 series, and C200 series */
static struct ichx_desc intel5_desc = {
.ngpio = 76,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Avoton */
static struct ichx_desc avoton_desc = {
/* Avoton has only 59 GPIOs, but we assume the first set of register
* (Core) has 32 instead of 31 to keep gpio-ich compliance
*/
.ngpio = 60,
.regs = avoton_regs,
.reglen = avoton_reglen,
.use_outlvl_cache = true,
};
static int ichx_gpio_request_regions(struct resource *res_base,
const char *name, u8 use_gpio)
{
int i;
if (!res_base || !res_base->start || !res_base->end)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
if (!(use_gpio & (1 << i)))
continue;
if (!request_region(
res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i], name))
goto request_err;
}
return 0;
request_err:
/* Clean up: release already requested regions, if any */
for (i--; i >= 0; i--) {
if (!(use_gpio & (1 << i)))
continue;
release_region(res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i]);
}
return -EBUSY;
}
static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
{
int i;
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
if (!(use_gpio & (1 << i)))
continue;
release_region(res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i]);
}
}
static int ichx_gpio_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_pm;
int err;
struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev);
if (!ich_info)
return -ENODEV;
ichx_priv.dev = pdev;
switch (ich_info->gpio_version) {
case ICH_I3100_GPIO:
ichx_priv.desc = &i3100_desc;
break;
case ICH_V5_GPIO:
ichx_priv.desc = &intel5_desc;
break;
case ICH_V6_GPIO:
ichx_priv.desc = &ich6_desc;
break;
case ICH_V7_GPIO:
ichx_priv.desc = &ich7_desc;
break;
case ICH_V9_GPIO:
ichx_priv.desc = &ich9_desc;
break;
case ICH_V10CORP_GPIO:
ichx_priv.desc = &ich10_corp_desc;
break;
case ICH_V10CONS_GPIO:
ichx_priv.desc = &ich10_cons_desc;
break;
case AVOTON_GPIO:
ichx_priv.desc = &avoton_desc;
break;
default:
return -ENODEV;
}
spin_lock_init(&ichx_priv.lock);
res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
ichx_priv.use_gpio = ich_info->use_gpio;
err = ichx_gpio_request_regions(res_base, pdev->name,
ichx_priv.use_gpio);
if (err)
return err;
ichx_priv.gpio_base = res_base;
/*
* If necessary, determine the I/O address of ACPI/power management
* registers which are needed to read the the GPE0 register for GPI pins
* 0 - 15 on some chipsets.
*/
if (!ichx_priv.desc->uses_gpe0)
goto init;
res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0);
if (!res_pm) {
pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n");
goto init;
}
if (!request_region(res_pm->start, resource_size(res_pm),
pdev->name)) {
pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n");
goto init;
}
ichx_priv.pm_base = res_pm;
init:
ichx_gpiolib_setup(&ichx_priv.chip);
err = gpiochip_add(&ichx_priv.chip);
if (err) {
pr_err("Failed to register GPIOs\n");
goto add_err;
}
pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base,
ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME);
return 0;
add_err:
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
release_region(ichx_priv.pm_base->start,
resource_size(ichx_priv.pm_base));
return err;
}
static int ichx_gpio_remove(struct platform_device *pdev)
{
int err;
err = gpiochip_remove(&ichx_priv.chip);
if (err) {
dev_err(&pdev->dev, "%s failed, %d\n",
"gpiochip_remove()", err);
return err;
}
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
release_region(ichx_priv.pm_base->start,
resource_size(ichx_priv.pm_base));
return 0;
}
static struct platform_driver ichx_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DRV_NAME,
},
.probe = ichx_gpio_probe,
.remove = ichx_gpio_remove,
};
module_platform_driver(ichx_gpio_driver);
MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");
MODULE_DESCRIPTION("GPIO interface for Intel ICH series");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:"DRV_NAME);

View File

@@ -15,8 +15,6 @@
#include <linux/err.h>
#include <linux/mutex.h>
//#include "I2CHostCommunication.h"
#define USE_SMBUS 1
/* definition */
@@ -115,7 +113,6 @@ static ssize_t show_info(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 b[4];
@@ -139,7 +136,6 @@ static ssize_t show_reset(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 b[1];
@@ -162,7 +158,6 @@ static ssize_t set_reset(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
//struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
@@ -179,7 +174,6 @@ static ssize_t show_ctl(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 b[1];
@@ -202,7 +196,6 @@ static ssize_t set_ctl(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
//struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;

View File

@@ -0,0 +1,281 @@
#include <linux/module.h>
#include <asm/io.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include "io_expander.h"
#include "inv_mux.h"
static struct mux_obj_s *mux_head_p = NULL;
/* ========== MUX object functions ==========
*/
int
_common_force_pull_gpio(int mem_addr,
int input,
int bit_offset){
unsigned int val = 0;
unsigned int targ = 0;
/* Get current value */
val = inl(mem_addr);
if (val == 0) {
SWPS_ERR("%s: inl:%d fail!\n", __func__, val);
return -1;
}
/* Count target value */
switch (input) {
case 0: /* Pull Low */
targ = (val & (~(1 << bit_offset)));
break;
case 1: /* Pull high */
targ = (val | (1 << bit_offset));
break;
default:
SWPS_ERR("%s: input state:%d incorrect!\n",
__func__, input);
return -1;
}
/* Setup gpio */
outl(targ, mem_addr);
if (targ != inl(mem_addr)){
SWPS_ERR("%s: outl:%d fail!\n", __func__, targ);
return -1;
}
SWPS_DEBUG("%s: done.\n", __func__);
return 0;
}
int
rangeley_force_pull_high(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
rangeley_force_pull_low(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
hedera_force_pull_high(struct mux_obj_s *self){
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5);
}
int
hedera_force_pull_low(struct mux_obj_s *self){
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5);
}
int
normal_gpio_pull_high(struct mux_obj_s *self){
return gpio_direction_output(self->gpio_num, 1);
}
int
normal_gpio_pull_low(struct mux_obj_s *self){
return gpio_direction_output(self->gpio_num, 0);
}
int
pca9548_reset_mux_all(struct mux_obj_s *self){
/* [Note] Power-on reset (PCA9548A-NXP)
* When power is applied to VDD, an internal Power-On Reset (POR)
* holds the PCA9548A in a reset condition until VDD has reached
* VPOR. At this point, the reset condition is released and the
* PCA9548A register and I2C-bus state machine are initialized to
* their default states (all zeroes) causing all the channels to
* be deselected. Thereafter, VDD must be lowered below 0.2 V for
* at least 5 us in order to reset the device.
*/
if (self->_pull_low(self) < 0) {
SWPS_ERR("%s: _pull_low fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS);
if (self->_pull_high(self) < 0) {
SWPS_ERR("%s: _pull_high fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS);
return 0;
}
int
common_reset_mux_all(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
init_gpio_4_force(struct mux_obj_s *self){
return 0;
}
int
init_gpio_4_normal(struct mux_obj_s *self){
int err = 0;
if (!gpio_is_valid(self->gpio_num)) {
SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num);
return -1;
}
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
if (err < 0) {
SWPS_ERR("%s: gpio_request fail <err>:%d <gpio>:%d\n",
__func__, err, self->gpio_num);
return -1;
}
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
return 0;
}
static int
_setup_muxctl_cb(struct mux_obj_s *self,
unsigned gpio){
char *mod_dsc = "ERR";
switch (gpio) {
case MUX_RST_GPIO_FORCE_RANGELEY:
self->gpio_num = gpio;
self->_pull_low = rangeley_force_pull_low;
self->_pull_high = rangeley_force_pull_high;
self->_init = init_gpio_4_force;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Rangeley force mode";
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_FORCE_HEDERA:
self->gpio_num = gpio;
self->_pull_low = hedera_force_pull_low;
self->_pull_high = hedera_force_pull_high;
self->_init = init_gpio_4_force;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Hedera force mode";
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_48_PAC9548:
self->gpio_num = gpio;
self->_pull_low = normal_gpio_pull_low;
self->_pull_high = normal_gpio_pull_high;
self->_init = init_gpio_4_normal;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Normal mode <gpio>:48";
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_69_PAC9548:
self->gpio_num = gpio;
self->_pull_low = normal_gpio_pull_low;
self->_pull_high = normal_gpio_pull_high;
self->_init = init_gpio_4_normal;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Normal mode <gpio>:69";
goto ok_setup_muxctl_cb;
default:
break;
}
SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio);
return -1;
ok_setup_muxctl_cb:
SWPS_INFO("muxctl: %s.\n", mod_dsc);
return 0;
}
/* ========== MUX public functions ==========
*/
void
clean_mux_gpio(void){
if (!mux_head_p) {
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
return;
}
if (gpio_is_valid(mux_head_p->gpio_num)) {
gpio_free(mux_head_p->gpio_num);
}
kfree(mux_head_p);
mux_head_p = NULL;
SWPS_DEBUG("%s: done.\n", __func__);
}
EXPORT_SYMBOL(clean_mux_gpio);
int
reset_mux_gpio(void){
if (!mux_head_p) {
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
return -1;
}
if (mux_head_p->reset(mux_head_p) < 0){
SWPS_ERR("%s: reset fail!\n", __func__);
return -1;
}
return 0;
}
EXPORT_SYMBOL(reset_mux_gpio);
int
init_mux_gpio(unsigned gpio){
/* Create MUX control object */
if (mux_head_p) {
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
clean_mux_gpio();
}
/* Currently, it is using single muxctl architecture.
* In the future, it may use the multi-muxctl if HW add new features.
* (Ex: Port power-status control)
*/
mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
if (!mux_head_p) {
SWPS_ERR("%s: kzalloc fail!\n", __func__);
return -1;
}
/* Initial MUX controller */
if (_setup_muxctl_cb(mux_head_p, gpio) < 0){
SWPS_ERR("%s: _setup_muxctl_cb fail!\n", __func__);
return -1;
}
if (mux_head_p->_init(mux_head_p) < 0) {
SWPS_ERR("%s: init() fail\n", __func__);
goto err_init_mux_gpio;
}
/* Setup default value */
if (mux_head_p->_pull_high(mux_head_p) < 0) {
SWPS_ERR("%s: setup default fail!\n", __func__);
goto err_init_mux_gpio;
}
return 0;
err_init_mux_gpio:
clean_mux_gpio();
return -1;
}
EXPORT_SYMBOL(init_mux_gpio);
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,36 @@
#ifndef INV_MUX_H
#define INV_MUX_H
/* MUX basic information */
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
/* MUX reset GPIO define */
#define MUX_RST_GPIO_FORCE (30100)
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
#define MUX_RST_GPIO_48_PAC9548 (48)
#define MUX_RST_GPIO_69_PAC9548 (69)
/* MUX relate value define */
#define MUX_RST_WAIT_MS (1)
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
struct mux_obj_s {
unsigned gpio_num;
int (*_pull_high)(struct mux_obj_s *self);
int (*_pull_low)(struct mux_obj_s *self);
int (*_init)(struct mux_obj_s *self);
int (*reset)(struct mux_obj_s *self);
};
void clean_mux_gpio(void);
int reset_mux_gpio(void);
int init_mux_gpio(unsigned gpio);
#endif /* INV_MUX_H */

View File

@@ -1,5 +1,4 @@
#include <linux/i2c.h>
//#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -10,7 +9,6 @@
#include <linux/platform_data/pca953x.h>
#include <linux/platform_data/at24.h>
//#include <asm/gpio.h>
#define IO_EXPAND_BASE 64
#define IO_EXPAND_NGPIO 16
@@ -111,39 +109,6 @@ static struct inv_i2c_board_info i2cdev_list[] = {
{bus_id(5), ARRAY_SIZE(i2c_device_info5), i2c_device_info5 }, //mux 3
};
/////////////////////////////////////////////////////////////////////////////////////////
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
.scl_pin = 8,
.sda_pin = 9,
.udelay = 5, //5:100kHz
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.scl_is_output_only = 0
};
static struct i2c_gpio_platform_data i2c_gpio_platdata1 = {
.scl_pin = 12,
.sda_pin = 11,
.udelay = 5, //5:100kHz
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.scl_is_output_only = 0
};
static struct platform_device device_i2c_gpio0 = {
.name = "i2c-gpio",
.id = 0, // adapter number
.dev.platform_data = &i2c_gpio_platdata0,
};
static struct platform_device device_i2c_gpio1 = {
.name = "i2c-gpio",
.id = 1, // adapter number
.dev.platform_data = &i2c_gpio_platdata1,
};
static int __init plat_redwood_x86_init(void)
{
struct i2c_adapter *adap = NULL;
@@ -153,24 +118,6 @@ static int __init plat_redwood_x86_init(void)
printk("el6661 plat_redwood_x86_init \n");
#if 0 //disable for ICOS
//use i2c-gpio
//register i2c gpio
//config gpio8,9 to gpio function
outl( inl(0x500) | (1<<8 | 1<<9), 0x500);
ret = platform_device_register(&device_i2c_gpio0);
if (ret) {
printk(KERN_ERR "i2c-gpio: device_i2c_gpio0 register fail %d\n", ret);
}
outl( inl(0x500) | (1<<11 | 1<<12), 0x500);
ret = platform_device_register(&device_i2c_gpio1);
if (ret) {
printk(KERN_ERR "i2c-gpio: device_i2c_gpio1 register fail %d\n", ret);
}
#endif
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
adap = i2c_get_adapter( i2cdev_list[i].ch );
@@ -190,7 +137,6 @@ static int __init plat_redwood_x86_init(void)
}
module_init(plat_redwood_x86_init);
//arch_initcall(plat_redwood_x86_init);
MODULE_AUTHOR("Inventec");
MODULE_DESCRIPTION("Redwood_x86 Platform devices");

View File

@@ -17,11 +17,8 @@
#include <linux/delay.h>
#include <linux/swab.h>
//#include "I2CHostCommunication.h"
#define USE_SMBUS 1
//#define offsetof(st, m) ((size_t)(&((st *)0)->m))
#define FAN_NUM 5
#define PSU_NUM 2
@@ -94,7 +91,6 @@ struct __attribute__ ((__packed__)) psoc_layout {
#define PWM_PSU_OFFSET PSOC_OFF(pwm_psu)
#define THERMAL_OFFSET PSOC_OFF(temp)
#define RPM_OFFSET PSOC_OFF(fan)
//#define RPM_PSU_OFFSET PSOC_OFF(fan_psu)
#define DIAG_FLAG_OFFSET PSOC_OFF(ctl)
#define FAN_LED_OFFSET PSOC_OFF(led_grn)
#define FAN_GPI_OFFSET PSOC_OFF(gpi_fan)
@@ -182,17 +178,6 @@ static ssize_t psoc_i2c_write(struct i2c_client *client, char *buf, unsigned off
#endif
}
static u32 psoc_read32(struct i2c_client *client, u8 offset)
{
u32 value = 0;
u8 buf[4];
if( psoc_i2c_read(client, buf, offset, 4) == 4)
value = (buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]);
return value;
}
static u16 psoc_read16(struct i2c_client *client, u8 offset)
{
u16 value = 0;
@@ -215,13 +200,6 @@ static u8 psoc_read8(struct i2c_client *client, u8 offset)
return value;
}
static int psoc_write_value(struct i2c_client *client, unsigned offset, u16 value)
{
//TBD
return 0;
}
//PSOC i2c bridge regsters
#define PSOC_I2C_STATUS PSOC_OFF(i2c_st)
#define PSOC_I2C_CNTRL PSOC_OFF(i2c_ctl)
@@ -497,8 +475,6 @@ static ssize_t set_switch_tmp(struct device *dev,
long temp = simple_strtol(buf, NULL, 10);
u16 temp2 = ( (temp/1000) <<8 ) & 0xFF00 ;
//printk("set_switch_tmp temp=%d, temp2=0x%x (%x,%x)\n", temp, temp2, ( ( (temp/1000) <<8 ) & 0xFF00 ), (( (temp%1000) / 10 ) & 0xFF));
mutex_lock(&data->update_lock);
psoc_i2c_write(client, (u8*)&temp2, SWITCH_TMP_OFFSET, 2);
mutex_unlock(&data->update_lock);
@@ -528,7 +504,6 @@ static ssize_t set_diag(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
//struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct psoc_data *data = i2c_get_clientdata(client);
u8 value = 0;
@@ -551,7 +526,6 @@ static ssize_t show_version(struct device *dev, struct device_attribute *da,
char *buf)
{
u16 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct psoc_data *data = i2c_get_clientdata(client);
@@ -675,7 +649,6 @@ static ssize_t show_psu(struct device *dev, struct device_attribute *da,
mutex_unlock(&data->update_lock);
status = value[1]<<8 | value[0];
//status1 = value[1]<<8 | value[0];
return sprintf(buf, "%ld\n", pmbus_reg2data_linear(status, (reg==PMBUS_READ_VOUT)?1:0) );
}
@@ -725,9 +698,6 @@ static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_OFFSET
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_OFFSET+1);
static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_OFFSET+2);
static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_OFFSET+3);
#if (FAN_NUM >= 5)
static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_OFFSET+4);
#endif
static SENSOR_DEVICE_ATTR(pwm_psu1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_PSU_OFFSET+0);
static SENSOR_DEVICE_ATTR(pwm_psu2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, PWM_PSU_OFFSET+1);
@@ -742,10 +712,6 @@ static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_rpm, 0, 4*2 + RPM_OFFSET)
static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_rpm, 0, 5*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_rpm, 0, 6*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_rpm, 0, 7*2 + RPM_OFFSET);
#if (FAN_NUM >= 5)
static SENSOR_DEVICE_ATTR(fan9_input, S_IRUGO, show_rpm, 0, 8*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_rpm, 0, 9*2 + RPM_OFFSET);
#endif
static SENSOR_DEVICE_ATTR(rpm_psu1, S_IRUGO, show_rpm, 0, 8*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(rpm_psu2, S_IRUGO, show_rpm, 0, 9*2 + RPM_OFFSET);
@@ -827,9 +793,6 @@ static struct attribute *psoc_attributes[] = {
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm4.dev_attr.attr,
#if (FAN_NUM >= 5)
//&sensor_dev_attr_pwm5.dev_attr.attr,
#endif
&sensor_dev_attr_pwm_psu1.dev_attr.attr,
&sensor_dev_attr_pwm_psu2.dev_attr.attr,
@@ -842,10 +805,6 @@ static struct attribute *psoc_attributes[] = {
&sensor_dev_attr_fan6_input.dev_attr.attr,
&sensor_dev_attr_fan7_input.dev_attr.attr,
&sensor_dev_attr_fan8_input.dev_attr.attr,
#if (FAN_NUM >= 5)
//&sensor_dev_attr_fan9_input.dev_attr.attr,
//&sensor_dev_attr_fan10_input.dev_attr.attr,
#endif
&sensor_dev_attr_rpm_psu1.dev_attr.attr,
&sensor_dev_attr_rpm_psu2.dev_attr.attr,
@@ -937,8 +896,6 @@ psoc_probe(struct i2c_client *client, const struct i2c_device_id *id)
struct psoc_data *data;
int status;
printk("+%s\n", __func__);
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -EIO;

View File

@@ -0,0 +1,752 @@
/*************************************************************************
*
* inv_swps.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef INV_SWPS_H
#define INV_SWPS_H
#include "transceiver.h"
#include "io_expander.h"
#include "inv_mux.h"
/* Module settings */
#define SWP_CLS_NAME "swps"
#define SWP_DEV_PORT "port"
#define SWP_DEV_MODCTL "module"
#define SWP_RESET_PWD "inventec"
#define SWP_POLLING_PERIOD (300) /* msec */
#define SWP_POLLING_ENABLE (1)
#define SWP_AUTOCONFIG_ENABLE (1)
/* Module information */
#define SWP_AUTHOR "Neil <liao.neil@inventec.com>"
#define SWP_DESC "Inventec port and transceiver driver"
#define SWP_VERSION "4.2.3"
#define SWP_LICENSE "GPL"
#define SWPS_KERN_VER_AF_3_10 (1)
/* Module status define */
#define SWP_STATE_NORMAL (0)
#define SWP_STATE_I2C_DIE (-91)
/* [Note]:
* Functions and mechanism for auto-detect platform type is ready,
* But HW and BIOS not ready! We need to wait them.
* So, please do not use PLATFORM_TYPE_AUTO until they are ready.
* (2016.06.13)
*/
#define PLATFORM_TYPE_AUTO (100)
#define PLATFORM_TYPE_MAGNOLIA (111)
#define PLATFORM_TYPE_MAGNOLIA_FNC (112)
#define PLATFORM_TYPE_REDWOOD (121)
#define PLATFORM_TYPE_REDWOOD_FSL (122)
#define PLATFORM_TYPE_HUDSON32I_GA (131)
#define PLATFORM_TYPE_SPRUCE (141)
#define PLATFORM_TYPE_CYPRESS_GA1 (151) /* Up -> Down */
#define PLATFORM_TYPE_CYPRESS_GA2 (152) /* Down -> Up */
#define PLATFORM_TYPE_CYPRESS_BAI (153) /* Down -> Up */
/* Current running platfrom */
#define PLATFORM_SETTINGS PLATFORM_TYPE_REDWOOD
/* Define platform flag and kernel version */
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA)
#define SWPS_MAGNOLIA (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA_FNC)
#define SWPS_MAGNOLIA (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD)
#define SWPS_REDWOOD (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD_FSL)
#define SWPS_REDWOOD_FSL (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_HUDSON32I_GA)
#define SWPS_HUDSON32I_GA (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SPRUCE)
#define SWPS_SPRUCE (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA1)
#define SWPS_CYPRESS_GA1 (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA2)
#define SWPS_CYPRESS_GA2 (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_BAI)
#define SWPS_CYPRESS_BAI (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#endif
struct inv_platform_s {
int id;
char name[64];
};
struct inv_ioexp_layout_s {
int ioexp_id;
int ioexp_type;
struct ioexp_addr_s addr[4];
};
struct inv_port_layout_s {
int port_id;
int chan_id;
int ioexp_id;
int ioexp_offset;
int transvr_type;
int chipset_type;
int lane_id[8];
};
/* ==========================================
* Inventec Platform Settings
* ==========================================
*/
struct inv_platform_s platform_map[] = {
{PLATFORM_TYPE_AUTO, "Auto-Detect" },
{PLATFORM_TYPE_MAGNOLIA, "Magnolia" },
{PLATFORM_TYPE_MAGNOLIA_FNC, "Magnolia_FNC" },
{PLATFORM_TYPE_REDWOOD, "Redwood" },
{PLATFORM_TYPE_REDWOOD_FSL, "Redwood_FSL" },
{PLATFORM_TYPE_HUDSON32I_GA, "Hudson32i" },
{PLATFORM_TYPE_SPRUCE, "Spruce" },
{PLATFORM_TYPE_CYPRESS_GA1, "Cypress_GA1" },
{PLATFORM_TYPE_CYPRESS_GA2, "Cypress_GA2" },
{PLATFORM_TYPE_CYPRESS_BAI, "Cypress_BAI" },
};
/* ==========================================
* Magnolia Layout configuration
* ==========================================
*/
#ifdef SWPS_MAGNOLIA
unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s magnolia_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_MAGINOLIA_NAB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{1, IOEXP_TYPE_MAGINOLIA_NAB, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{2, IOEXP_TYPE_MAGINOLIA_NAB, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{3, IOEXP_TYPE_MAGINOLIA_NAB, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{4, IOEXP_TYPE_MAGINOLIA_NAB, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{5, IOEXP_TYPE_MAGINOLIA_NAB, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{6, IOEXP_TYPE_MAGINOLIA_7AB, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[1] = I/O Expander 7 B */
},
};
struct inv_port_layout_s magnolia_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 16} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 15} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 14} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 13} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 24} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 23} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 22} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 21} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 28} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 27} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 26} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 25} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 32} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 31} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 30} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 29} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 48} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 47} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 46} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 45} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 52} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 51} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 50} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 49} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 56} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 55} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 54} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 53} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 60} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 59} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 58} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 57} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 64} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 63} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 62} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 61} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 68} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 67} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 66} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 65} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 72} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 71} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 70} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 69} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 76} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 75} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 74} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 73} },
{48, 58, 6, 0, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} },
{50, 60, 6, 2, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} },
{52, 62, 6, 4, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} },
};
#endif
/* ==========================================
* Redwood Layout configuration
* ==========================================
*/
#ifdef SWPS_REDWOOD
unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s redwood_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
};
struct inv_port_layout_s redwood_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} },
{ 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} },
{ 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} },
{ 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} },
{ 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} },
{ 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} },
{ 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} },
{ 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} },
{ 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} },
{ 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} },
{10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} },
{11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} },
{12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} },
{13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} },
{14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} },
{15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} },
{16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} },
{17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} },
{18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} },
{19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} },
{20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} },
{21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} },
{23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} },
{24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
{28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113,114,115,116} },
{29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121,122,123,124} },
{31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125,126,127,128} },
};
#endif
/* ==========================================
* Hudson32i Layout configuration
* ==========================================
*/
#ifdef SWPS_HUDSON32I_GA
unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_HUDSON32IGA_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */
},
{1, IOEXP_TYPE_HUDSON32IGA_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */
},
{2, IOEXP_TYPE_HUDSON32IGA_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */
},
{3, IOEXP_TYPE_HUDSON32IGA_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */
},
};
struct inv_port_layout_s hudson32iga_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 1, 2, 3, 4} },
{ 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 5, 6, 7, 8} },
{ 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 9, 10, 11, 12} },
{ 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 13, 14, 15, 16} },
{ 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 17, 18, 19, 20} },
{ 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 21, 22, 23, 24} },
{ 6, 12, 0, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 25, 26, 27, 28} },
{ 7, 13, 0, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 29, 30, 31, 32} },
{ 8, 14, 1, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 33, 34, 35, 36} },
{ 9, 15, 1, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 37, 38, 39, 40} },
{10, 16, 1, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 41, 42, 43, 44} },
{11, 17, 1, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 45, 46, 47, 48} },
{12, 18, 1, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 49, 50, 51, 52} },
{13, 19, 1, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 53, 54, 55, 56} },
{14, 20, 1, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 57, 58, 59, 60} },
{15, 21, 1, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 61, 62, 63, 64} },
{16, 22, 2, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 65, 66, 67, 68} },
{17, 23, 2, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 69, 70, 71, 72} },
{18, 24, 2, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 73, 74, 75, 76} },
{19, 25, 2, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} },
{20, 26, 2, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} },
{21, 27, 2, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 85, 86, 87, 88} },
{22, 28, 2, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 89, 90, 91, 92} },
{23, 29, 2, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 93, 94, 95, 96} },
{24, 30, 3, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} },
{25, 31, 3, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} },
{26, 32, 3, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} },
{27, 33, 3, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} },
{28, 34, 3, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {113,114,115,116} },
{29, 35, 3, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {117,118,119,120} },
{30, 36, 3, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {121,122,123,124} },
{31, 37, 3, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {125,126,127,128} },
};
#endif
/* ==========================================
* Spruce Layout configuration
* ==========================================
*/
#ifdef SWPS_SPRUCE
unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s spruce_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_SPRUCE_7AB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[2] = I/O Expander 7B */
},
};
struct inv_port_layout_s spruce_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} },
{ 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} },
{ 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} },
{ 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} },
{ 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} },
{ 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} },
};
#endif
/* ==========================================
* Cypress Layout configuration (Inventec version [Up->Down])
* ==========================================
*/
#ifdef SWPS_CYPRESS_GA1
unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s cypress_ga1_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} },
{48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
};
#endif
/* ==========================================
* Cypress Layout configuration (Inventec version [Down->Up])
* ==========================================
*/
#ifdef SWPS_CYPRESS_GA2
unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s cypress_ga2_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} },
{ 1, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} },
{ 2, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} },
{ 3, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} },
{ 4, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} },
{ 5, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} },
{ 6, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} },
{ 7, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} },
{ 8, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} },
{ 9, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} },
{10, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} },
{11, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} },
{12, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} },
{13, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} },
{14, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} },
{15, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} },
{16, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} },
{17, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} },
{18, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} },
{19, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} },
{20, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} },
{21, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} },
{22, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} },
{23, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} },
{24, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} },
{25, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} },
{26, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} },
{27, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} },
{28, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} },
{29, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} },
{30, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} },
{31, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} },
{32, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} },
{33, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} },
{34, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} },
{35, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} },
{36, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} },
{37, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} },
{38, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} },
{39, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} },
{40, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} },
{41, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} },
{42, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} },
{43, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} },
{44, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} },
{45, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} },
{46, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} },
{47, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} },
{48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
};
#endif
/* ==========================================
* Cypress Layout configuration (BaiDu version)
* ==========================================
*/
#ifdef SWPS_CYPRESS_BAI
unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s cypress_b_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} },
{ 2, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} },
{ 4, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} },
{ 6, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} },
{ 8, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} },
{10, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} },
{12, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} },
{14, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} },
{16, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} },
{18, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} },
{20, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} },
{22, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} },
{24, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} },
{26, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} },
{28, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} },
{30, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} },
{32, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} },
{34, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} },
{36, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} },
{38, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} },
{40, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} },
{42, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} },
{44, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} },
{46, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} },
{48, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{50, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{52, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{54, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
};
#endif
/* ==========================================
* Redwood_fsl Layout configuration
* ==========================================
*/
#ifdef SWPS_REDWOOD_FSL
unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
};
struct inv_port_layout_s redwood_fsl_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} },
{ 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} },
{ 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} },
{ 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} },
{ 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} },
{ 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} },
{ 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} },
{ 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} },
{ 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} },
{ 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} },
{10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} },
{11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} },
{12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} },
{13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} },
{14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} },
{15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} },
{16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} },
{17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} },
{18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} },
{19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} },
{20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} },
{21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} },
{23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} },
{24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
{28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113,114,115,116} },
{29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121,122,123,124} },
{31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125,126,127,128} },
};
#endif
#endif /* INV_SWPS_H */

View File

@@ -0,0 +1,358 @@
/*************************************************************************
*
* inv_vpd.c
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "inv_vpd.h"
#include "onie_tlvinfo.h"
static int vpd_major;
static struct class *vpd_class_p = NULL;
static char cEeprom[SYS_EEPROM_MAX_SIZE];
static DEFINE_MUTEX(vpd_mutex);
static int
__swp_match(struct device *dev,
#ifdef VPD_KERN_VER_AF_3_10
const void *data){
#else
void *data){
#endif
char *name = (char *)data;
if (strcmp(dev_name(dev), name) == 0)
return 1;
return 0;
}
static
int get_vpd_data(struct i2c_client *pi2c_client, int i_offset, char *c_buf)
{
int iRet;
read_eeprom( pi2c_client, cEeprom);
iRet = tlvinfo_decode_tlv(cEeprom, i_offset,c_buf);
return iRet;
}
static
int write_vpd_data(struct i2c_client *pi2c_client, int i_offset, char *c_buf)
{
int iErr = 0;
if (read_eeprom(pi2c_client, cEeprom)) {
printk(KERN_ERR "write vpd data eror at %d-%s\n", __LINE__, __FUNCTION__);
return -1;
}
if (tlvinfo_delete_tlv(cEeprom, i_offset) == TRUE) {
}
if (c_buf) {
if(!tlvinfo_add_tlv(cEeprom, i_offset , c_buf)) {
printk(KERN_ERR "write vpd data eror at %d-%s\n", __LINE__, __FUNCTION__);
iErr = -1;
} else {
iErr = prog_eeprom(pi2c_client,cEeprom);
}
}
return iErr;
}
static struct device *
get_swpdev_by_name(char *name){
struct device *dev = class_find_device(vpd_class_p,
NULL,
name,
__swp_match);
return dev;
}
static ssize_t
store_attr_vpd(struct device *dev_p,
struct device_attribute *attr_p,
const char *buf_p,
size_t count){
struct i2c_client *pi2c_client = dev_get_drvdata(dev_p);
struct vpd_device_attribute *attr = to_vpd_dev_attr(attr_p);
int iOffset = attr->index;
int iErr , iLen;
char *pChar;
if (!pi2c_client){
return -ENODEV;
}
mutex_lock(&vpd_mutex);
//-strip 0x0a in the last byte.
for (iLen = 0, pChar = (char *)buf_p;
iLen < 255 && *pChar != 0;
iLen++, pChar++) ;
if (iLen !=0 && *pChar == 0 && *(pChar-1) == 0x0a)
*(pChar - 1) = 0;
//-
iErr = write_vpd_data( pi2c_client, iOffset, (char *)buf_p);
mutex_unlock(&vpd_mutex);
return count;
}
static ssize_t
show_attr_vpd(struct device *dev_p,
struct device_attribute *attr_p,
char *buf_p){
struct i2c_client *pi2c_client = dev_get_drvdata(dev_p);
struct vpd_device_attribute *attr = to_vpd_dev_attr(attr_p);
int iOffset = attr->index;
int iErr , iLen;
if (!pi2c_client){
return -ENODEV;
}
mutex_lock(&vpd_mutex);
iErr = get_vpd_data( pi2c_client, iOffset, buf_p);
mutex_unlock(&vpd_mutex);
if( iErr <= 0 )
iLen = 0;
else
iLen = snprintf(buf_p, TLV_DECODE_VALUE_MAX_LEN, "%s\n", buf_p);
return iLen;
}
/* ================= Vpd attribute ========================
*/
static VPD_DEVICE_ATTR(product_name ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_PRODUCT_NAME );
static VPD_DEVICE_ATTR(pn ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_PART_NUMBER );
static VPD_DEVICE_ATTR(sn ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_SERIAL_NUMBER );
static VPD_DEVICE_ATTR(base_mac_addr,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MAC_BASE );
static VPD_DEVICE_ATTR(man_date ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MANUF_DATE );
static VPD_DEVICE_ATTR(dev_ver ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_DEVICE_VERSION );
static VPD_DEVICE_ATTR(label_rev ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_LABEL_REVISION );
static VPD_DEVICE_ATTR(plat_name ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_PLATFORM_NAME );
static VPD_DEVICE_ATTR(ldr_ver ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_ONIE_VERSION );
static VPD_DEVICE_ATTR(mac_addr ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MAC_SIZE );
static VPD_DEVICE_ATTR(manufacturer ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MANUF_NAME );
static VPD_DEVICE_ATTR(country_code ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MANUF_COUNTRY );
static VPD_DEVICE_ATTR(vendor_name ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_VENDOR_NAME );
static VPD_DEVICE_ATTR(diag_ver ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_DIAG_VERSION );
static VPD_DEVICE_ATTR(service_tag ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_SERVICE_TAG );
static VPD_DEVICE_ATTR(vendor_ext ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_VENDOR_EXT );
static VPD_DEVICE_ATTR(crc32 ,S_IRUGO, show_attr_vpd, NULL, TLV_CODE_CRC_32 );
static void
clean_vpd_common(void)
{
dev_t dev_num;
struct device *device_p;
device_p = get_swpdev_by_name(VPD_DEVICE);
if (device_p){
dev_num = MKDEV(vpd_major, 1);
device_unregister(device_p);
device_destroy(vpd_class_p, dev_num);
}
VPD_DEBUG("%s: done.\n", __func__);
}
static struct register_attr VpdRegAttr[] ={
{ &vpd_dev_attr_product_name.dev_attr, "vpd_dev_attr_product_name"},
{ &vpd_dev_attr_pn.dev_attr, "vpd_dev_attr_pn"},
{ &vpd_dev_attr_sn.dev_attr, "vpd_dev_attr_sn"},
{ &vpd_dev_attr_base_mac_addr.dev_attr, "vpd_dev_attr_base_mac_addr"},
{ &vpd_dev_attr_man_date.dev_attr, "vpd_dev_attr_man_date"},
{ &vpd_dev_attr_dev_ver.dev_attr, "vpd_dev_attr_dev_ver"},
{ &vpd_dev_attr_label_rev.dev_attr, "vpd_dev_attr_label_rev"},
{ &vpd_dev_attr_plat_name.dev_attr, "vpd_dev_attr_plat_name"},
{ &vpd_dev_attr_ldr_ver.dev_attr, "vpd_dev_attr_ldr_ver"},
{ &vpd_dev_attr_mac_addr.dev_attr, "vpd_dev_attr_mac_addr"},
{ &vpd_dev_attr_manufacturer.dev_attr, "vpd_dev_attr_manufacturer"},
{ &vpd_dev_attr_country_code.dev_attr, "vpd_dev_attr_country_code"},
{ &vpd_dev_attr_vendor_name.dev_attr, "vpd_dev_attr_vendor_name"},
{ &vpd_dev_attr_diag_ver.dev_attr, "vpd_dev_attr_diag_ver"},
{ &vpd_dev_attr_service_tag.dev_attr, "vpd_dev_attr_service_tag"},
{ &vpd_dev_attr_vendor_ext.dev_attr, "vpd_dev_attr_vendor_ext"},
{ &vpd_dev_attr_crc32.dev_attr, "vpd_dev_attr_crc32"},
};
#define VPD_ENTRY_SIZE (sizeof(VpdRegAttr)/sizeof(struct register_attr))
static int
register_vpd_attr(struct device *device_p){
char *err_attr = NULL;
int i;
for( i = 0 ; i <VPD_ENTRY_SIZE ;i++ ){
if(device_create_file(device_p, VpdRegAttr[ i ].attr) < 0) {
err_attr = VpdRegAttr[ i ].errmsg;
goto err_register_vpd_attr;
}
}
return 0;
err_register_vpd_attr:
VPD_ERR("%s: %s\n", __func__, err_attr);
return -1;
}
static int
register_vpd_device(void)
{
int minor_comm = 0; /* Default minor number for common device */
dev_t dev_num = MKDEV(vpd_major, minor_comm);
char *err_msg = "ERROR";
struct device *device_p = NULL;
struct i2c_adapter *adap;
struct i2c_client *vpd_i2c_client = NULL;
vpd_i2c_client = kzalloc(sizeof(*vpd_i2c_client), GFP_KERNEL);
if (!vpd_i2c_client){
printk(KERN_ERR "can not kzalloc client:%d", VPD_I2C_BUS);
goto err_register_vpd_device;
}
adap = i2c_get_adapter(VPD_I2C_BUS);
vpd_i2c_client->adapter = adap;
vpd_i2c_client->addr = VPD_I2C_ADDR;
device_p = device_create(vpd_class_p, /* struct class *cls */
NULL, /* struct device *parent */
dev_num, /* dev_t devt */
vpd_i2c_client, /* void *private_data */
VPD_DEVICE); /* const char *fmt */
if (IS_ERR(device_p)){
err_msg = "device_create fail";
goto err_register_vpd_device_1;
}
if (register_vpd_attr(device_p) < 0) {
err_msg = "register_vpd_attr fail";
goto err_register_vpd_device_2;
}
return 0;
err_register_vpd_device_2:
device_unregister(device_p);
device_destroy(vpd_class_p, dev_num);
err_register_vpd_device_1:
kfree(vpd_i2c_client);
vpd_i2c_client = NULL;
err_register_vpd_device:
VPD_ERR("%s: %s\n", __func__, err_msg);
return -1;
}
static int
register_vpd_module(void)
{
dev_t vpd_devt = 0;
if (alloc_chrdev_region(&vpd_devt, 0, 1, VPD_DEVICE) < 0){
VPD_WARN("Allocate VPD MAJOR failure! \n");
goto err_register_vpd_module;
}
vpd_major = MAJOR(vpd_devt);
/* Create class object */
vpd_class_p = class_create(THIS_MODULE, EEPROM_CLASS);
if (IS_ERR(vpd_class_p)) {
VPD_ERR("Create class failure! \n");
goto err_register_vpd_module_1;
}
return 0;
err_register_vpd_module_1:
unregister_chrdev_region(MKDEV(vpd_major, 0), 1);
err_register_vpd_module:
return -1;
}
static int
init_vpd_common(void)
{
char *err_msg = "ERR";
if (register_vpd_device() < 0) {
err_msg = "register_vpd_device fail";
goto err_init_vpd_common;
}
return 0;
err_init_vpd_common:
VPD_ERR("%s: %s\n", __func__, err_msg);
return -1;
}
static int __init
vpd_module_init(void)
{
if (register_vpd_module() < 0){
goto err_vpd_module_init;
}
if (init_vpd_common() < 0){
goto err_vpd_module_init_1;
}
VPD_INFO("Inventec vpd module V.%s initial success.\n", VPD_VERSION);
return 0;
err_vpd_module_init_1:
class_unregister(vpd_class_p);
class_destroy(vpd_class_p);
unregister_chrdev_region(MKDEV(vpd_major, 0), 1);
err_vpd_module_init:
VPD_ERR("Inventec vpd module V.%s initial failure.\n", VPD_VERSION);
return -1;
}
static void __exit
vpd_module_exit(void)
{
clean_vpd_common();
class_unregister(vpd_class_p);
class_destroy(vpd_class_p);
unregister_chrdev_region(MKDEV(vpd_major, 0), 1);
VPD_INFO("Remove Inventec vpd module success.\n");
}
/* Module information */
MODULE_AUTHOR(VPD_AUTHOR);
MODULE_DESCRIPTION(VPD_DESC);
MODULE_VERSION(VPD_VERSION);
MODULE_LICENSE(VPD_LICENSE);
module_init(vpd_module_init);
module_exit(vpd_module_exit);

View File

@@ -0,0 +1,63 @@
/*************************************************************************
*
* inv_vpd.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef INV_VPD_H
#define INV_VPD_H
#define EEPROM_CLASS "eeprom"
#define VPD_DEVICE "vpd"
#define VPD_AUTHOR "Neil <liao.neil@inventec.com>"
#define VPD_DESC "Inventec eeprom vpd driver"
#define VPD_VERSION "1.0.0"
#define VPD_LICENSE "GPL"
#define VPD_I2C_BUS (0)
#define VPD_I2C_ADDR (0x53)
#define VPD_KERN_VER_AF_3_10 (1)
struct register_attr {
struct device_attribute *attr;
char * errmsg;
};
struct vpd_device_attribute{
struct device_attribute dev_attr;
int index;
};
#define to_vpd_dev_attr(_dev_attr) \
container_of(_dev_attr, struct vpd_device_attribute, dev_attr)
#define VPD_ATTR(_name, _mode, _show, _store, _index) \
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
.index = _index }
#define VPD_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
struct vpd_device_attribute vpd_dev_attr_##_name \
= VPD_ATTR(_name, _mode, _show, _store, _index)
#define VPD_INFO(fmt, args...) printk( KERN_INFO "[VPD] " fmt, ##args)
#define VPD_WARN(fmt, args...) printk( KERN_WARNING "[VPD] " fmt, ##args)
#define VPD_ERR(fmt, args...) printk( KERN_ERR "[VPD] " fmt, ##args)
#ifdef DEBUG_VPD
# define VPD_DEBUG(fmt, args...) printk( KERN_DEBUG "[VPD] " fmt, ##args)
#else
# define VPD_DEBUG(fmt, args...)
#endif
#endif /* INV_VPD_H */

View File

@@ -0,0 +1,185 @@
/*************************************************************************
*
* io_expander.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef IO_EXPANDER_H
#define IO_EXPANDER_H
#include <linux/types.h>
/* IOEXP type define (SFP series) */
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
#define IOEXP_TYPE_CYPRESS_NABC (10102)
/* IOEXP type define (QSFP series) */
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
#define IOEXP_TYPE_SPRUCE_7AB (10206)
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
/* IOEXP mode define */
#define IOEXP_MODE_POLLING (19000)
#define IOEXP_MODE_DIRECT (19001)
/* IOEXP state define */
#define STATE_IOEXP_NORMAL (0)
#define STATE_IOEXP_INIT (-1)
#define STATE_IOEXP_ABNORMAL (-2)
/* IOEXP error code define */
#define ERR_IOEXP_NOTSUPPORT (-100)
#define ERR_IOEXP_UNINIT (-101)
#define ERR_IOEXP_BADCONF (-102)
#define ERR_IOEXP_ABNORMAL (-103)
#define ERR_IOEXP_NOSTATE (-104)
#define ERR_IOEXP_BADINPUT (-105)
#define ERR_IOEXP_UNEXCPT (-199)
#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args)
#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args)
#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args)
#ifdef DEBUG_SWPS
# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args)
#else
# define SWPS_DEBUG(fmt, args...)
#endif
struct ioexp_addr_s {
int chan_id;
int chip_addr;
int read_offset[8];
int write_offset[8];
int conf_offset[8];
uint8_t data_default[8];
uint8_t conf_default[8];
};
struct ioexp_i2c_s {
int chip_id;
struct i2c_client *i2c_client_p;
struct ioexp_i2c_s *next;
};
struct ioexp_bitmap_s {
int chip_id; /* IOEXP chip id */
int ioexp_voffset; /* IOEXP virtual offset */
int bit_shift;
};
struct ioexp_map_s {
int chip_amount; /* Number of chips that IOEXP object content */
int data_width; /* Number of (Read/Write/Config) bytes */
struct ioexp_addr_s *map_addr; /* Chip address info */
struct ioexp_bitmap_s map_present[8]; /* IOEXP for SFP / QSFP */
struct ioexp_bitmap_s map_tx_disable[8]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_tx_fault[8]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_rxlos[8]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_reset[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_lpmod[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_modsel[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_hard_rs0[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_hard_rs1[8]; /* IOEXP for QSFP */
};
struct ioexp_data_s {
uint8_t data[8];
};
struct ioexp_obj_s {
/* ============================
* Object public property
* ============================
*/
int ioexp_id;
int ioexp_type;
/* ============================
* Object private property
* ============================
*/
struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */
struct ioexp_map_s *ioexp_map_p;
struct ioexp_obj_s *next;
struct ioexp_i2c_s *i2c_head_p;
struct mutex lock;
int mode;
int state;
/* ===========================================
* Object public functions
* ===========================================
*/
int (*get_present)(struct ioexp_obj_s *self, int virt_offset);
int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset);
int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset);
int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset);
int (*get_reset)(struct ioexp_obj_s *self, int virt_offset);
int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset);
int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset);
int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset);
int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset);
int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val);
/* ===========================================
* Object private functions
* ===========================================
*/
int (*init)(struct ioexp_obj_s *self);
int (*check)(struct ioexp_obj_s *self);
int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name);
int (*fsm_4_direct)(struct ioexp_obj_s* self);
int (*fsm_4_polling)(struct ioexp_obj_s* self);
};
struct ioexp_obj_s* get_ioexp_obj(int ioexp_id);
int create_ioexp_obj(int ioexp_id,
int ioexp_type,
struct ioexp_addr_s *addr_map_p,
int run_mode);
int init_ioexp_objs(void);
int check_ioexp_objs(void);
void clean_ioexp_objs(void);
void unlock_ioexp_all(void);
int lock_ioexp_all(void);
int check_channel_tier_1(void);
int resync_channel_tier_1(void);
/* Macro for bit control */
#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift)))
#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift)))
#endif /* IO_EXPANDER_H */

View File

@@ -0,0 +1,765 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include "onie_tlvinfo.h"
/* Set to 1 if we've read EEPROM into memory */
static int has_been_read = 0;
int read_sys_eeprom(struct i2c_client *pi2c_client,void *eeprom_data, int offset, int len);
int write_sys_eeprom(struct i2c_client *pi2c_client, void *eeprom_data, int len);
static inline int is_multicast_ether_addr(const u_int8_t *addr)
{
return 0x01 & addr[0];
}
static inline int is_zero_ether_addr(const u_int8_t *addr)
{
return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
}
static inline int is_valid_ether_addr(const u_int8_t *addr)
{
return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
}
static unsigned long crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
static unsigned long crc32(unsigned char const *buf, unsigned int size)
{
unsigned char *p = (unsigned char*)buf;
unsigned long crc = 0;
crc = crc ^ ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}
static int set_bytes(char *buf, const char *string, int * converted_accum)
{
char *p = (char *) string;
int i;
uint byte;
if (!p) {
printk("ERROR: NULL string passed in.\n");
return -1;
}
/* Convert string to bytes */
for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0);
i++) {
while ((*p == ' ') || (*p == '\t') || (*p == ',') ||
(*p == ';')) {
p++;
}
if (*p != 0) {
if (!isdigit(*p)) {
printk("ERROR: Non-digit found in byte string: (%s)\n", string);
return -1;
}
byte = strtoul(p, &p, 0);
if (byte >= 256) {
printk("ERROR: The value specified is greater than 255: (%u) " \
"in string: %s\n", byte, string);
return -1;
}
buf[i] = byte & 0xFF;
}
}
if ((i == TLV_VALUE_MAX_LEN) && (*p != 0)) {
printk("ERROR: Trying to assign too many bytes "
"(max: %d) in string: %s\n", TLV_VALUE_MAX_LEN, string);
return -1;
}
*converted_accum = i;
return 0;
}
/*
* set_date
*
* Validates the format of the data string
*
* This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss)
* and validates that the format is correct. If so the string is copied
* to the supplied buffer.
*/
static int set_date(char *buf, const char *string)
{
int i;
if (!string) {
printk("ERROR: NULL date string passed in.\n");
return -1;
}
if (strlen(string) != 19) {
printk("ERROR: Date strlen() != 19 -- %zd\n", strlen(string));
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", string);
return -1;
}
for (i = 0; string[i] != 0; i++) {
switch (i) {
case 2:
case 5:
if (string[i] != '/') {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
case 10:
if (string[i] != ' ') {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
case 13:
case 16:
if (string[i] != ':') {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
default:
if (!isdigit(string[i])) {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
}
}
strcpy(buf, string);
return 0;
}
/*
* is_valid_tlv
*
* Perform basic sanity checks on a TLV field. The TLV is pointed to
* by the parameter provided.
* 1. The type code is not reserved (0x00 or 0xFF)
*/
static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv)
{
return((tlv->type != 0x00) && (tlv->type != 0xFF));
}
/*
* set_mac
*
* Converts a string MAC address into a binary buffer.
*
* This function takes a pointer to a MAC address string
* (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number).
* The string format is verified and then converted to binary and
* stored in a buffer.
*/
static int set_mac(char *buf, const char *string)
{
char *p = (char *) string;
int i;
int err = 0;
char *end;
if (!p) {
printk("ERROR: NULL mac addr string passed in.\n");
return -1;
}
if (strlen(p) != 17) {
printk("ERROR: MAC address strlen() != 17 -- %zd\n", strlen(p));
printk("ERROR: Bad MAC address format: %s\n", string);
return -1;
}
for (i = 0; i < 17; i++) {
if ((i % 3) == 2) {
if (p[i] != ':') {
err++;
printk("ERROR: mac: p[%i] != :, found: `%c'\n",
i, p[i]);
break;
}
continue;
} else if (!isxdigit(p[i])) {
err++;
printk("ERROR: mac: p[%i] != hex digit, found: `%c'\n",
i, p[i]);
break;
}
}
if (err != 0) {
printk("ERROR: Bad MAC address format: %s\n", string);
return -1;
}
/* Convert string to binary */
for (i = 0, p = (char *)string; i < 6; i++) {
buf[i] = p ? strtoul(p, &end, 16) : 0;
if (p) {
p = (*end) ? end + 1 : end;
}
}
if (!is_valid_ether_addr((char *)buf)) {
printk("ERROR: MAC address must not be 00:00:00:00:00:00, "
"a multicast address or FF:FF:FF:FF:FF:FF.\n");
printk("ERROR: Bad MAC address format: %s\n", string);
return -1;
}
return 0;
}
/*
* is_valid_tlvinfo_header
*
* Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM
* data pointed to by the parameter:
* 1. First 8 bytes contain null-terminated ASCII string "TlvInfo"
* 2. Version byte is 1
* 3. Total length bytes contain value which is less than or equal
* to the allowed maximum (2048-11)
*
*/
static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr)
{
int max_size = TLV_TOTAL_LEN_MAX;
return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) &&
(hdr->version == TLV_INFO_VERSION) &&
(be16_to_cpu(hdr->totallen) <= max_size) );
}
/*
* decode_tlv_value
*
* Decode a single TLV value into a string.
* The validity of EEPROM contents and the TLV field have been verified
* prior to calling this function.
*/
#define DECODE_NAME_MAX 20
static void decode_tlv_value(tlvinfo_tlv_t * tlv, char* value)
{
int i;
switch (tlv->type) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_MANUF_DATE:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
memcpy(value, tlv->value, tlv->length);
value[tlv->length] = 0;
break;
case TLV_CODE_MAC_BASE:
snprintf(value, MAX_STRING_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3], tlv->value[4], tlv->value[5]);
break;
case TLV_CODE_DEVICE_VERSION:
snprintf(value, MAX_STRING_SIZE, "%u", tlv->value[0]);
break;
case TLV_CODE_MAC_SIZE:
snprintf(value, MAX_STRING_SIZE, "%u", (tlv->value[0] << 8) | tlv->value[1]);
break;
case TLV_CODE_VENDOR_EXT:
value[0] = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length);
i++) {
snprintf(value, MAX_STRING_SIZE, "%s 0x%02X", value, tlv->value[i]);
}
break;
case TLV_CODE_CRC_32:
snprintf(value, MAX_STRING_SIZE, "0x%02X%02X%02X%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3]);
break;
default:
value[0] = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length);
i++) {
snprintf(value, MAX_STRING_SIZE, "%s 0x%02X", value, tlv->value[i]);
}
break;
}
}
/*
* is_checksum_valid
*
* Validate the checksum in the provided TlvInfo EEPROM data. First,
* verify that the TlvInfo header is valid, then make sure the last
* TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
* and compare it to the value stored in the EEPROM CRC-32 TLV.
*/
static bool is_checksum_valid(u_int8_t *eeprom)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_crc;
unsigned int calc_crc;
unsigned int stored_crc;
// Is the eeprom header valid?
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return(FALSE);
}
// Is the last TLV a CRC?
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) -
(sizeof(tlvinfo_tlv_t) + 4)];
if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) {
return(FALSE);
}
// Calculate the checksum
calc_crc = crc32((void *)eeprom, sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) |
(eeprom_crc->value[2] << 8) | eeprom_crc->value[3]);
//printk(KERN_ERR "[SWPS] cal_crc =0x%x, stored_crc =0x%x\n", calc_crc, stored_crc);
//return(calc_crc == stored_crc);
return 1;
}
/*
* update_crc
*
* This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then
* one is added. This function should be called after each update to the
* EEPROM structure, to make sure the CRC is always correct.
*/
static void update_crc(u_int8_t *eeprom)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_crc;
unsigned int calc_crc;
// Is the eeprom header valid?
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return;
}
// Is the last TLV a CRC?
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) -
(sizeof(tlvinfo_tlv_t) + 4)];
if (eeprom_crc->type != TLV_CODE_CRC_32) {
if ((be16_to_cpu(eeprom_hdr->totallen) + sizeof(tlvinfo_tlv_t) + 4) >
TLV_TOTAL_LEN_MAX) {
return;
}
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(
eeprom_hdr->totallen)];
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) +
sizeof(tlvinfo_tlv_t) + 4);
eeprom_crc->type = TLV_CODE_CRC_32;
}
eeprom_crc->length = 4;
// Calculate the checksum
calc_crc = crc32((void *)eeprom,
sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF;
eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF;
eeprom_crc->value[2] = (calc_crc >> 8) & 0xFF;
eeprom_crc->value[3] = (calc_crc >> 0) & 0xFF;
}
/*
* show_eeprom
*
* Display the contents of the EEPROM
*/
/*
* read_eeprom
*
* Read the EEPROM into memory, if it hasn't already been read.
*/
int read_eeprom( struct i2c_client *pi2c_client, u_int8_t *eeprom)
{
int ret;
tlvinfo_header_t *eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t *eeprom_tlv = (tlvinfo_tlv_t *)&eeprom[
sizeof(tlvinfo_header_t)];
if (has_been_read)
return 0;
/* Read the header */
ret = read_sys_eeprom( pi2c_client,(void *)eeprom_hdr, 0, sizeof(tlvinfo_header_t));
/* If the header was successfully read, read the TLVs */
if ((ret == 0) && is_valid_tlvinfo_header(eeprom_hdr)) {
ret = read_sys_eeprom( pi2c_client, (void *)eeprom_tlv, sizeof(tlvinfo_header_t),
be16_to_cpu(eeprom_hdr->totallen));
}
// If the contents are invalid, start over with default contents
if(!is_valid_tlvinfo_header(eeprom_hdr))
printk(KERN_ERR
"Notice: Invalid TLV header found. Using default contents--1.\n");
if(!is_checksum_valid(eeprom))
printk(KERN_ERR
"Notice: Invalid TLV checksum found. Using default contents--2.\n");
if ( !is_valid_tlvinfo_header(eeprom_hdr) || !is_checksum_valid(eeprom) ){
strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING);
eeprom_hdr->version = TLV_INFO_VERSION;
eeprom_hdr->totallen = cpu_to_be16(0);
update_crc(eeprom);
}
has_been_read = 1;
return ret;
}
EXPORT_SYMBOL(read_eeprom);
/*
* prog_eeprom
* Write the EEPROM data from CPU memory to the hardware.
*/
int prog_eeprom(struct i2c_client *pi2c_client, u_int8_t * eeprom)
{
int ret = 0;
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
int eeprom_len;
eeprom_len = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
ret = write_sys_eeprom( pi2c_client, eeprom, eeprom_len);
if (ret) {
printk("Programming failed.\n");
return -1;
}
has_been_read = 0;
return 0;
}
EXPORT_SYMBOL(prog_eeprom);
/*
* tlvinfo_find_tlv
*
* This function finds the TLV with the supplied code in the EERPOM.
* An offset from the beginning of the EEPROM is returned in the
* eeprom_index parameter if the TLV is found.
*/
bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode,
int *eeprom_index)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
int eeprom_end;
// Make sure the EEPROM contents are valid
if (!is_valid_tlvinfo_header(eeprom_hdr) || !is_checksum_valid(eeprom)) {
return(FALSE);
}
// Search through the TLVs, looking for the first one which matches the
// supplied type code.
*eeprom_index = sizeof(tlvinfo_header_t);
eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
while (*eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index];
if (!is_valid_tlv(eeprom_tlv)) {
return(FALSE);
}
if (eeprom_tlv->type == tcode) {
return(TRUE);
}
*eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
return(FALSE);
}
/*
* tlvinfo_decode_tlv
*
* This function finds the TLV with the supplied code in the EERPOM
* and decodes the value into the buffer provided.
*/
bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, char* value)
{
int eeprom_index;
tlvinfo_tlv_t * eeprom_tlv;
// Find the TLV and then decode it
if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
decode_tlv_value(eeprom_tlv, value);
return TRUE;
}
return FALSE;
}
EXPORT_SYMBOL(tlvinfo_decode_tlv);
/*
* tlvinfo_delete_tlv
*
* This function deletes the TLV with the specified type code from the
* EEPROM.
*/
bool tlvinfo_delete_tlv(u_int8_t * eeprom, u_int8_t code)
{
int eeprom_index;
int tlength;
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
// Find the TLV and then move all following TLVs "forward"
if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
tlength = sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index+tlength],
sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen) -
eeprom_index - tlength);
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) -
tlength);
update_crc(eeprom);
return(TRUE);
}
return(FALSE);
}
EXPORT_SYMBOL(tlvinfo_delete_tlv);
/*
* tlvinfo_add_tlv
*
* This function adds a TLV to the EEPROM, converting the value (a string) to
* the format in which it will be stored in the EEPROM.
*/
#define MAX_TLV_VALUE_LEN 256
bool tlvinfo_add_tlv(u_int8_t * eeprom, int tcode, char * strval)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
int new_tlv_len = 0;
u_int32_t value;
char data[MAX_TLV_VALUE_LEN];
int eeprom_index;
int max_size = TLV_TOTAL_LEN_MAX;
// Encode each TLV type into the format to be stored in the EERPOM
switch (tcode) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
strncpy(data, strval, MAX_TLV_VALUE_LEN);
if( strlen(strval) >= MAX_TLV_VALUE_LEN )
new_tlv_len = MAX_TLV_VALUE_LEN;
else
new_tlv_len = strlen(strval);
break;
case TLV_CODE_DEVICE_VERSION:
value = strtoul(strval, NULL, 0);
if (value >= 256) {
printk("ERROR: Device version must be 255 or less. Value " \
"supplied: %u", value);
return(FALSE);
}
data[0] = value & 0xFF;
new_tlv_len = 1;
break;
case TLV_CODE_MAC_SIZE:
value = strtoul(strval, NULL, 0);
if (value >= 65536) {
printk("ERROR: MAC Size must be 65535 or less. Value " \
"supplied: %u", value);
return(FALSE);
}
data[0] = (value >> 8) & 0xFF;
data[1] = value & 0xFF;
new_tlv_len = 2;
break;
case TLV_CODE_MANUF_DATE:
if (set_date(data, strval) != 0) {
return(FALSE);
}
new_tlv_len = 19;
break;
case TLV_CODE_MAC_BASE:
if (set_mac(data, strval) != 0) {
return(FALSE);
}
new_tlv_len = 6;
break;
case TLV_CODE_CRC_32:
printk("WARNING: The CRC TLV is set automatically and cannot be set " \
"manually.\n");
return(FALSE);
case TLV_CODE_VENDOR_EXT:
default:
if (set_bytes(data, strval, &new_tlv_len) != 0 ) {
return(FALSE);
}
break;
}
// Is there room for this TLV?
if ((be16_to_cpu(eeprom_hdr->totallen) + sizeof(tlvinfo_tlv_t) +
new_tlv_len) > max_size) {
printk("ERROR: There is not enough room in the EERPOM to save data.\n");
return(FALSE);
}
// Add TLV at the end, overwriting CRC TLV if it exists
if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) {
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen)
- sizeof(tlvinfo_tlv_t) - 4);
} else {
eeprom_index = sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen);
}
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
eeprom_tlv->type = tcode;
eeprom_tlv->length = new_tlv_len;
memcpy(eeprom_tlv->value, data, new_tlv_len);
// Update the total length and calculate (add) a new CRC-32 TLV
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) +
sizeof(tlvinfo_tlv_t) + new_tlv_len);
update_crc(eeprom);
return(TRUE);
}
EXPORT_SYMBOL(tlvinfo_add_tlv);
/*
* read_sys_eeprom - read the hwinfo from i2c EEPROM
*/
int read_sys_eeprom(struct i2c_client *pi2c_client,void *eeprom_data, int offset, int len)
{
int iRet = 0;
int i = 0;
unsigned char ucBuf[2];
u_int8_t *c;
unsigned short usAddr = SYS_EEPROM_OFFSET + offset;
c = eeprom_data;
for (i = 0; i < len; i++) {
ucBuf[0] = (usAddr & 0xFF00) >> 8;
ucBuf[1] = (usAddr & 0x00FF);
iRet = i2c_smbus_write_byte_data(pi2c_client, ucBuf[0], ucBuf[1]);
if( iRet < 0 ){
printk(KERN_ERR"Error!! VPD data read error\n");
return -1;
}
*c = i2c_smbus_read_byte(pi2c_client);
c++; usAddr++;
}
return 0;
}
/*
* write_sys_eeprom - write the hwinfo to i2c EEPROM
*/
int write_sys_eeprom(struct i2c_client *pi2c_client, void *eeprom_data, int len)
{
int iRet = 0;
int i = 0;
u_int8_t *c;
unsigned short usAddr = SYS_EEPROM_OFFSET;
unsigned char ucBuf[3];
c = eeprom_data;
for (i = 0; i < len; i++) {
ucBuf[ 0 ] = (usAddr & 0xFF00) >>8 ;
ucBuf[ 1 ] = (usAddr & 0x00FF);
ucBuf[ 2 ] = *c;
iRet = i2c_smbus_write_word_data( pi2c_client, ucBuf[0], (ucBuf[2] << 8 | ucBuf[1]));
if (iRet < 0 ){
printk(KERN_ERR"Error!! VPD data write error . \n");
return -1;
}
c++; usAddr++;
msleep_interruptible(10);
}
return 0;
}
void update_eeprom_header(u_int8_t *eeprom)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING);
eeprom_hdr->version = TLV_INFO_VERSION;
eeprom_hdr->totallen = cpu_to_be16(0);
update_crc(eeprom);
}

View File

@@ -0,0 +1,150 @@
/*
* The Definition of the TlvInfo EEPROM format can be found at onie.org or
* github.com/onie
*/
#include <linux/types.h>
#define strtoul simple_strtoul
#define FALSE 0
#define TRUE (!FALSE)
#define MAX_STRING_SIZE 128
/*
* Tlvinf header: Layout of the header for the TlvInfo format
*
* See the end of this file for details of this eeprom format
*/
struct __attribute__ ((__packed__)) tlvinfo_header_s {
char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */
u_int8_t version; /* 0x08 Structure version */
u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */
};
typedef struct tlvinfo_header_s tlvinfo_header_t;
// Header Field Constants
#define TLV_INFO_ID_STRING "TlvInfo"
#define TLV_INFO_VERSION 0x01
#define TLV_TOTAL_LEN_MAX (SYS_EEPROM_SIZE - sizeof(tlvinfo_header_t))
/*
* TlvInfo TLV: Layout of a TLV field
*/
struct __attribute__ ((__packed__)) tlvinfo_tlv_s {
u_int8_t type;
u_int8_t length;
u_int8_t value[0];
};
typedef struct tlvinfo_tlv_s tlvinfo_tlv_t;
/* Maximum length of a TLV value in bytes */
#define TLV_VALUE_MAX_LEN 255
/**
* The TLV Types.
*
* Keep these in sync with tlv_code_list in cmd_sys_eeprom.c
*/
#define TLV_CODE_PRODUCT_NAME 0x21
#define TLV_CODE_PART_NUMBER 0x22
#define TLV_CODE_SERIAL_NUMBER 0x23
#define TLV_CODE_MAC_BASE 0x24
#define TLV_CODE_MANUF_DATE 0x25
#define TLV_CODE_DEVICE_VERSION 0x26
#define TLV_CODE_LABEL_REVISION 0x27
#define TLV_CODE_PLATFORM_NAME 0x28
#define TLV_CODE_ONIE_VERSION 0x29
#define TLV_CODE_MAC_SIZE 0x2A
#define TLV_CODE_MANUF_NAME 0x2B
#define TLV_CODE_MANUF_COUNTRY 0x2C
#define TLV_CODE_VENDOR_NAME 0x2D
#define TLV_CODE_DIAG_VERSION 0x2E
#define TLV_CODE_SERVICE_TAG 0x2F
#define TLV_CODE_VENDOR_EXT 0xFD
#define TLV_CODE_CRC_32 0xFE
#define TLV_CODE_EEPROM_DATA 0x00
/*
* Struct for displaying the TLV codes and names.
*/
struct tlv_code_desc {
u_int8_t m_code;
char* m_name;
};
/*
* List of TLV codes and names.
*/
static const struct tlv_code_desc tlv_code_list[] = {
{ TLV_CODE_PRODUCT_NAME , "Product Name"},
{ TLV_CODE_PART_NUMBER , "Part Number"},
{ TLV_CODE_SERIAL_NUMBER , "Serial Number"},
{ TLV_CODE_MAC_BASE , "Base MAC Address"},
{ TLV_CODE_MANUF_DATE , "Manufacture Date"},
{ TLV_CODE_DEVICE_VERSION , "Device Version"},
{ TLV_CODE_LABEL_REVISION , "Label Revision"},
{ TLV_CODE_PLATFORM_NAME , "Platform Name"},
{ TLV_CODE_ONIE_VERSION , "Loader Version"},
{ TLV_CODE_MAC_SIZE , "MAC Addresses"},
{ TLV_CODE_MANUF_NAME , "Manufacturer"},
{ TLV_CODE_MANUF_COUNTRY , "Country Code"},
{ TLV_CODE_VENDOR_NAME , "Vendor Name"},
{ TLV_CODE_DIAG_VERSION , "Diag Version"},
{ TLV_CODE_SERVICE_TAG , "Service Tag"},
{ TLV_CODE_VENDOR_EXT , "Vendor Extension"},
{ TLV_CODE_CRC_32 , "CRC-32"},
};
static inline const char* tlv_type2name(u_int8_t type)
{
char* name = "Unknown";
int i;
for (i = 0; i < sizeof(tlv_code_list)/sizeof(tlv_code_list[0]); i++) {
if (tlv_code_list[i].m_code == type) {
name = tlv_code_list[i].m_name;
break;
}
}
return name;
}
/*
* The max decode value is currently for the 'raw' type or the 'vendor
* extension' type, both of which have the same decode format. The
* max decode string size is computed as follows:
*
* strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1
*
*/
#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1)
/*
* Each platform must define the following platform-specific macros
* in sys_eeprom_platform.h:
* SYS_EEPROM_SIZE: size of usable eeprom
* SYS_EEPROM_I2C_DEVICE: i2c-bus
* SYS_EEPROM_I2C_ADDR: address on the bus
* The following may also be defined in sys_eeprom_platform.h, else
* the defaults with take over:
* SYS_EEPROM_MAX_SIZE: Total size of the eeprom
* SYS_EEPROM_OFFSET: offset from where the ONIE header starts
*/
#define SYS_EEPROM_MAX_SIZE 2048
#define SYS_EEPROM_OFFSET 0
#define SYS_EEPROM_SIZE SYS_EEPROM_MAX_SIZE
#define SYS_EEPROM_I2C_DEVICE "/dev/i2c-0"
#define SYS_EEPROM_I2C_ADDR 0x53
#if (SYS_EEPROM_SIZE + SYS_EEPROM_OFFSET > SYS_EEPROM_MAX_SIZE)
#error SYS_EEPROM_SIZE + SYS_EEPROM_OFFSET is greater than SYS_EEPROM_MAX_SIZE
#endif
// Access functions to onie_tlvinfo
void show_eeprom(u_int8_t *eeprom);
int read_eeprom(struct i2c_client *pi2c_client, u_int8_t *eeprom);
int prog_eeprom(struct i2c_client *pi2c_client,u_int8_t * eeprom);
void update_eeprom_header(u_int8_t *eeprom);
bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode, int *eeprom_index);
bool tlvinfo_delete_tlv(u_int8_t * eeprom, u_int8_t code);
bool tlvinfo_add_tlv(u_int8_t * eeprom, int tcode, char * strval);
bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, char* value);

View File

@@ -0,0 +1,811 @@
/*************************************************************************
*
* transceiver.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef TRANSCEIVER_H
#define TRANSCEIVER_H
#include <linux/types.h>
/* advanced features control */
#define TRANSVR_INFO_DUMP_ENABLE (1)
#define TRANSVR_INFO_CACHE_ENABLE (1)
#define TRANSVR_UEVENT_ENABLE (1)
/* Transceiver type define */
#define TRANSVR_TYPE_UNKNOW_1 (0x00)
#define TRANSVR_TYPE_UNKNOW_2 (0xff)
#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */
#define TRANSVR_TYPE_QSFP (0x0c)
#define TRANSVR_TYPE_QSFP_PLUS (0x0d)
#define TRANSVR_TYPE_QSFP_28 (0x11)
#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */
#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */
#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */
#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */
/* Transceiver class for base info */
#define TRANSVR_CLASS_UNSPECIFIED (0)
#define TRANSVR_CLASS_ERROR (-26001)
#define TRANSVR_CLASS_1G (26001)
#define TRANSVR_CLASS_10G (26011)
#define TRANSVR_CLASS_25G (26021)
#define TRANSVR_CLASS_40G (26041)
#define TRANSVR_CLASS_100G (26101)
#define TRANSVR_CLASS_NO_SPERARABLE (26901)
#define TRANSVR_CLASS_EXTEND_COMP (26902)
/* Transceiver class for Optical 1G */
#define TRANSVR_CLASS_OPTICAL (27000)
#define TRANSVR_CLASS_OPTICAL_100 (27001)
#define TRANSVR_CLASS_OPTICAL_1G (27002)
#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003)
#define TRANSVR_CLASS_OPTICAL_1G_SX (27004)
#define TRANSVR_CLASS_OPTICAL_1G_LX (27005)
#define TRANSVR_CLASS_OPTICAL_1G_EX (27006)
/* Transceiver class for Optical 10G */
#define TRANSVR_CLASS_OPTICAL_10G (27010)
#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011)
#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012)
#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013)
#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014)
#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015)
#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016)
#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017)
#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018)
/* Transceiver class for Optical 25G */
#define TRANSVR_CLASS_OPTICAL_25G (27020)
#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021)
#define TRANSVR_CLASS_OPTICAL_25G_SR (27022)
#define TRANSVR_CLASS_OPTICAL_25G_LR (27023)
#define TRANSVR_CLASS_OPTICAL_25G_ER (27024)
/* Transceiver class for Optical 40G */
#define TRANSVR_CLASS_OPTICAL_40G (27040)
#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041)
#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042)
#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043)
#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044)
/* Transceiver class for Optical 100G */
#define TRANSVR_CLASS_OPTICAL_100G (27100)
#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101)
#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102)
#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103)
#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104)
#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105)
/* Transceiver class for Copper */
#define TRANSVR_CLASS_COPPER (28000)
#define TRANSVR_CLASS_COPPER_L1_1G (28001)
#define TRANSVR_CLASS_COPPER_L1_10G (28011)
#define TRANSVR_CLASS_COPPER_L4_10G (28012)
#define TRANSVR_CLASS_COPPER_L1_25G (28021)
#define TRANSVR_CLASS_COPPER_L4_40G (28041)
#define TRANSVR_CLASS_COPPER_L4_100G (28101)
/* Transceiver class for Base-T */
#define TRANSVR_CLASS_BASE_T_1000 (29001)
#define TRANSVR_CLASS_BASE_T_1000_up (29002)
/* For uevent message */
#define TRANSVR_UEVENT_KEY_IF "IF_TYPE"
#define TRANSVR_UEVENT_KEY_SP "IF_SPEED"
#define TRANSVR_UEVENT_KEY_LANE "IF_LANE"
#define TRANSVR_UEVENT_UNKNOW "UNKNOW"
#define TRANSVR_IF_KR "KR"
#define TRANSVR_IF_KR4 "KR4"
#define TRANSVR_IF_SR "SR"
#define TRANSVR_IF_SR4 "SR4"
#define TRANSVR_IF_SFI "SFI"
#define TRANSVR_IF_IF_GMII "GMII"
#define TRANSVR_IF_IF_XGMII "XGMII"
#define TRANSVR_IF_SP_100 "100"
#define TRANSVR_IF_SP_1G "1000"
#define TRANSVR_IF_SP_10G "10000"
#define TRANSVR_IF_SP_25G "25000"
#define TRANSVR_IF_SP_40G "40000"
#define TRANSVR_IF_SP_100G "100000"
/* Transceiver mode define */
#define TRANSVR_MODE_DIRECT (21000)
#define TRANSVR_MODE_POLLING (21001)
/* Transceiver state define
* [Note]
* 1. State is used to represent the state of "Transceiver" and "Object".
* 2. State for different target has different means. The description as following:
*/
#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */
#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */
#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */
#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */
#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */
#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */
#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */
/* Task state define */
#define STATE_T_TASK_WAIT (110)
#define STATE_T_TASK_DONE (0)
#define STATE_T_TASK_INIT (-110)
#define STATE_T_TASK_FAIL (-410)
/* Event for task handling */
#define EVENT_TRANSVR_TASK_WAIT (2101)
#define EVENT_TRANSVR_TASK_DONE (0)
#define EVENT_TRANSVR_TASK_FAIL (-2101)
/* Event for initial handling */
#define EVENT_TRANSVR_INIT_UP (2201)
#define EVENT_TRANSVR_INIT_DOWN (1)
#define EVENT_TRANSVR_INIT_REINIT (-2201)
#define EVENT_TRANSVR_INIT_FAIL (-2202)
/* Event for others */
#define EVENT_TRANSVR_RELOAD_FAIL (-2301)
#define EVENT_TRANSVR_EXCEP_INIT (-2401)
#define EVENT_TRANSVR_EXCEP_UP (-2402)
#define EVENT_TRANSVR_EXCEP_DOWN (-2403)
#define EVENT_TRANSVR_EXCEP_SWAP (-2404)
#define EVENT_TRANSVR_EXCEP_EXCEP (-2405)
#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406)
#define EVENT_TRANSVR_I2C_CRASH (-2501)
/* Transceiver error code define */
#define ERR_TRANSVR_UNINIT (-201)
#define ERR_TRANSVR_UNPLUGGED (-202)
#define ERR_TRANSVR_ABNORMAL (-203)
#define ERR_TRANSVR_NOSTATE (-204)
#define ERR_TRANSVR_NOTSUPPORT (-205)
#define ERR_TRANSVR_BADINPUT (-206)
#define ERR_TRANSVR_UPDATE_FAIL (-207)
#define ERR_TRANSVR_RELOAD_FAIL (-208)
#define ERR_TRANSVR_INIT_FAIL (-209)
#define ERR_TRANSVR_UNDEFINED (-210)
#define ERR_TRANSVR_TASK_FAIL (-211)
#define ERR_TRANSVR_TASK_BUSY (-212)
#define ERR_TRANSVR_UEVENT_FAIL (-213)
#define ERR_TRANSVR_FUNC_DISABLE (-214)
#define ERR_TRANSVR_I2C_CRASH (-297)
#define ERR_TRNASVR_BE_ISOLATED (-298)
#define ERR_TRANSVR_UNEXCPT (-299)
/* For debug */
#define DEBUG_TRANSVR_INT_VAL (-99)
#define DEBUG_TRANSVR_HEX_VAL (0xfe)
#define DEBUG_TRANSVR_STR_VAL "ERROR"
/* For system internal */
#define VAL_TRANSVR_COMID_ARREESS (0x50)
#define VAL_TRANSVR_COMID_OFFSET (0x00)
#define VAL_TRANSVR_8472_READY_ADDR (0x51)
#define VAL_TRANSVR_8472_READY_PAGE (-1)
#define VAL_TRANSVR_8472_READY_OFFSET (110)
#define VAL_TRANSVR_8472_READY_BIT (0)
#define VAL_TRANSVR_8472_READY_VALUE (0)
#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff)
#define VAL_TRANSVR_8436_READY_ADDR (0x50)
#define VAL_TRANSVR_8436_READY_PAGE (-1)
#define VAL_TRANSVR_8436_READY_OFFSET (2)
#define VAL_TRANSVR_8436_READY_BIT (0)
#define VAL_TRANSVR_8436_READY_VALUE (0)
#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff)
#define VAL_TRANSVR_8436_PWD_ADDR (0x50)
#define VAL_TRANSVR_8436_PWD_PAGE (-1)
#define VAL_TRANSVR_8436_PWD_OFFSET (123)
#define VAL_TRANSVR_PAGE_FREE (-99)
#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127)
#define VAL_TRANSVR_PAGE_SELECT_DELAY (5)
#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999)
#define VAL_TRANSVR_FUNCTION_DISABLE (-1)
#define STR_TRANSVR_SFP "SFP"
#define STR_TRANSVR_QSFP "QSFP"
#define STR_TRANSVR_QSFP_PLUS "QSFP+"
#define STR_TRANSVR_QSFP28 "QSFP28"
/* For transvr buf len */
#define LEN_TRANSVR_S_STR (16)
#define LEN_TRANSVR_M_STR (32)
#define LEN_TRANSVR_L_STR (64)
/* Optical wavelength */
#define VAL_OPTICAL_WAVELENGTH_SR (850)
#define VAL_OPTICAL_WAVELENGTH_LR (1310)
#define VAL_OPTICAL_WAVELENGTH_ER (1550)
/* BCM chip type define */
#define BCM_CHIP_TYPE_TRIDENT_2 (31001) /* Magnolia, Hudson32i, Spruce */
#define BCM_CHIP_TYPE_TOMAHAWK (31002) /* Redwood, Cypress */
/* Info from transceiver EEPROM */
struct eeprom_map_s {
int addr_br; int page_br; int offset_br; int length_br;
int addr_cdr; int page_cdr; int offset_cdr; int length_cdr;
int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev;
int addr_connector; int page_connector; int offset_connector; int length_connector;
int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type;
int addr_extbr; int page_extbr; int offset_extbr; int length_extbr;
int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id;
int addr_id; int page_id; int offset_id; int length_id;
int addr_eeprom; int page_eeprom; int offset_eeprom; int length_eeprom;
int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm;
int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf;
int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1;
int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2;
int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3;
int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4;
int addr_option; int page_option; int offset_option; int length_option;
int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id;
int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am;
int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em;
int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los;
int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power;
int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0;
int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1;
int addr_temp; int page_temp; int offset_temp; int length_temp;
int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp;
int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext;
int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias;
int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable;
int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq;
int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault;
int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power;
int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name;
int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn;
int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev;
int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn;
int addr_voltage; int page_voltage; int offset_voltage; int length_voltage;
int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength;
};
struct transvr_worker_s;
/* Class of transceiver object */
struct transvr_obj_s {
/* ========== Object private property ==========
* [Prop]: id
* [Desc]: Type of serial transceiver.
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h
*/
uint8_t id;
/* [Prop]: connector
* [Desc]: Connector type.
* [Note]: SFP : A0h / 2
* QSFP: 00h / 130
*/
uint8_t connector;
/* [Prop]: transvr_comp
* [Desc]: Transceiver compliance code.
* [Note]: SFP: SFF-8472
* - Normal : A0h / offset 3-10
* - Extended: A0h / offset 36
* QSFP: SFF-8436 & SFF-8636
* - Normal : 00h / offset 131-138
* - Extended: 00h / offset 192
*/
uint8_t transvr_comp[8];
uint8_t transvr_comp_ext;
/* [Prop]: vendor_name
* [Desc]: SFP vendor name (ASCII 16 byte char).
* [Note]: ex:FINISAR CORP.
*/
char *vendor_name;
/* [Prop]: vendor_pn
* [Desc]: Part number provided by SFP vendor (ASCII 16 byte char).
* [Note]:
*/
char *vendor_pn;
/* [Prop]: vendor_rev
* [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char).
* [Note]:
*/
char *vendor_rev;
/* [Prop]: vendor_sn
* [Desc]: Serial number provided by vendor (ASCII 16 byte char).
* [Note]:
*/
char *vendor_sn;
/* [Prop]: Extended identifier
* [Desc]: SFP:
* => None
*
* QSFP:
* => This byte contained two information:
* (1) Power consumption class
* (2) CDR function present
* [Note]: Bit description as below:
* [SFP]
* None
*
* [QSFP]
* (1) Power consumption class:
* Class 1: 1.5W (Bit6-7 = 00:)
* Class 2: 2.0W (Bit6-7 = 01:)
* Class 3: 2.5W (Bit6-7 = 10:)
* Class 4: 3.5W (Bit6-7 = 11:)
* Class 5: 4.0W (Bit0-1 = 01:)
* Class 6: 4.5W (Bit0-1 = 10:)
* Class 7: 5.0W (Bit0-1 = 11:)
* (2) CDR function present:
* Bit2: 0 = No CDR in RX
* 1 = CDR present in RX
* Bit3: 0 = No CDR in TX
* 1 = CDR present in TX
*/
uint8_t ext_id;
/* [Prop]: br
* [Desc]: Nominal bit rate, units of 100 MBits/sec.
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh
* has val: 0x67
* no val :
*/
uint8_t br;
/* [Prop]: extbr
* [Desc]: Extended br (00h/222)
* [Desc]: Nominal bit rate per channel, units of 250 Mbps.
* Complements. Byte 140. See Table 32A.
*/
uint8_t extbr;
/* [Prop]: len_sm
* [Desc]: Length (single mode)-(100's)m
* [Note]: This value specifies the link length that is supported by the transceiver
* while operating in compliance with the applicable standards using single mode
* fiber. The value is in units of 100 meters. A value of 255 means that the
* transceiver supports a link length greater than 25.4 km. A value of zero means
* that the transceiver does not support single mode fiber or that the length
* information must be determined from the transceiver technology.
*/
int len_sm;
/* [Prop]: len_smf
* [Desc]: Length (single mode)-km
* [Note]: Addition to EEPROM data from original GBIC definition. This value specifies
* the link length that is supported by the transceiver while operating in
* compliance with the applicable standards using single mode fiber. The value
* is in units of kilometers. A value of 255 means that the transceiver supports
* a link length greater than 254 km. A value of zero means that the transceiver
* does not support single mode fiber or that the length information must be
* determined from the transceiver technology.
*/
int len_smf;
/* [Prop]: len_om1
* [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m
* [Note]: The value is in units of 10 meters. A value of 255 means that the
* transceiver supports a link length greater than 2.54 km. A value of
* zero means that the transceiver does not support 50 micron multi-mode
* fiber or that the length information must be determined from the transceiver
* technology.
*/
int len_om1;
/* [Prop]: len_om2
* [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m
* [Note]: The value is in units of 10 meters. A value of 255 means that the
* transceiver supports a link length greater than 2.54 km. A value of
* zero means that the transceiver does not support 50 micron multi-mode
* fiber or that the length information must be determined from the transceiver
* technology.
*/
int len_om2;
/* [Prop]: len_om3
* [Desc]: Length (50um, OM3)
* [Note]: This value specifies link length that is supported by the transceiver while
* operating in compliance with applicable standards using 50 micron multimode
* OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255
* means that the transceiver supports a link length greater than 2.54 km. A value
* of zero means that the transceiver does not support 50 micron multimode fiber
* or that the length information must be determined from the transceiver technology.
*/
int len_om3;
/* [Prop]: len_om4
* [Desc]: Length (50um, OM4) and Length (Active Cable or Copper)
* [Note]: For optical links, this value specifies link length that is supported by the
* transceiver while operating in compliance with applicable standards using 50 micron
* multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of
* 255 means that the transceiver supports a link length greater than 2.54 km. A value
* of zero means that the transceiver does not support 50 micron multimode fiber or that
* the length information must be determined from the transceiver codes specified in Table 5-3.
*
* For copper links, this value specifies minimum link length supported by the transceiver
* while operating in compliance with applicable standards using copper cable. For active
* cable, this value represents actual length. The value is in units of 1 meter. A value of 255
* means the transceiver supports a link length greater than 254 meters. A value of zero means
* the transceiver does not support copper or active cables or the length information must be
* determined from transceiver technology. Further information about cable design, equalization,
* and connectors is usually required to guarantee meeting a particular length requirement.
*/
int len_om4;
/* [Prop]: comp_rev
* [Desc]: SFF spec revision compliance
* [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver
* complies with. (unsigned integer)
*/
uint8_t comp_rev;
/* [Prop]: CDR
* [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal
* retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which
* directs traffic around the internal CDR. (Reference: SFF-8636)
* [Note]: value=0xff: ON.
* value=0x00: OFF.
*/
uint8_t cdr;
/* [Prop]: rate_id
* [Desc]: Soft Rate Select 0(RX).
* [Note]: 1. Addr: A0h / Offset: 13
* 2. Value description:
* 00h Unspecified
* 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1)
* 02h SFF-8431 (8/4/2G Rx Rate_Select only)
* 03h Unspecified *
* 04h SFF-8431 (8/4/2G Tx Rate_Select only)
* 05h Unspecified *
* 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select)
* 07h Unspecified *
* 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G
* 09h Unspecified *
* 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only,
* Low=8G/4G
* 0Bh Unspecified *
* 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)
* High=32G only, Low = 16G/8G
* 0Dh Unspecified *
* 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking
* modes of the internal signal conditioner, retimer or CDR, according
* to the logic table defined in Table 10-2, High Bit Rate
* (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode,
* the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11)
* and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1.
* 0Fh Unspecified *
* 10h-FFh Unallocated
*/
int rate_id;
/* [Prop]: soft_rs0
* [Desc]: Soft Rate Select 0(RX).
* [Note]: 1. Writing '1' selects full bandwidth operation.
* 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value.
* 3. Default at power up is logic zero/low
* 4. Addr: A2h / Offset: 110 / Bit: 3
*/
uint8_t soft_rs0;
/* [Prop]: soft_rs1
* [Desc]: Soft Rate Select 1(TX).
* [Note]: 1. Writing '1' selects full bandwidth TX operation.
* 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value.
* 3. Default at power up is logic zero/low
* 4. Addr: A2h / Offset: 118 / Bit: 3
*/
uint8_t soft_rs1;
/* [Prop]: diag_type
* [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92)
* [Note]: Description in SFF-8472 as below:
* Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance
* with this document.
* Bit6: Digital diagnostic monitoring implemented (described in this document).
* Must be '1' for compliance with this document.
* Bit5 Internally calibrated
* Bit4 Externally calibrated
* Bit3 Received power measurement type.0 = OMA, 1 = average power
* Bit2 Address change required see section above, "addressing modes"
* Bit1-0 Unallocated
*/
uint8_t diag_type;
/* [Prop]: curr_temp
* [Desc]: Transceiver Current Temperature (A2h/96-97)
* [Note]: 1. Dependent on diag_type.
* 2. 96: High byte
* 3. 97: Low byte
* 4. This feature only for SFP
*/
uint8_t curr_temp[2];
/* [Prop]: curr_vol
* [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23)
* [Note]: 1. Dependent on diag_type.
* 2. 98: High byte
* 3. 99: Low byte
* 4. This feature only for SFP
* 5. Internally measured transceiver supply voltage. Represented
* as a 16 bit unsigned integer with the voltage defined as the
* full 16 bit value (0-65535) with LSB equal to 100 uVolt,
* yielding a total range of 0 to +6.55 Volts
*/
uint8_t curr_voltage[2];
/* [Prop]: curr_tx_bias
* [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27)
* [Note]: 1. Dependent on diag_type.
* 2. 100: High byte
* 3. 101: Low byte
* 4. This feature only for SFP
* 5. Measured TX bias current in uA. Represented as a 16 bit unsigned
* integer with the current defined as the full 16 bit value (0-65535)
* with LSB equal to 2 uA, yielding a total range of 0 to 131 mA.
* Accuracy is vendor specific but must be better than 10% of the
* manufacturer's nominal value over specified operating temperature
* and voltage.
*/
uint8_t curr_tx_bias[8];
/* [Prop]: curr_tx_power
* [Desc]: Transceiver TX Output Power (A2h/102-103)
* [Note]: 1. Dependent on diag_type.
* 2. 102: High byte
* 3. 103: Low byte
* 4. This feature only for SFP
* 5. Measured TX output power in mW. Represented as a 16 bit unsigned
* integer with the power defined as the full 16 bit value (0-65535)
* with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW
* (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of
* laser monitor photodiode current. It is factory calibrated to absolute
* units using the most representative fiber output type. Accuracy is
* vendor specific but must be better than 3dB over specified temperature
* and voltage. Data is not valid when the transmitter is disabled.
*/
uint8_t curr_tx_power[8];
/* [Prop]: curr_tx_power
* [Desc]: Transceiver TX Output Power (A2h/102-103)
* [Note]: 1. Dependent on diag_type.
* 2. 102: High byte
* 3. 103: Low byte
* 4. This feature only for SFP
* 5. Measured RX received optical power in mW. Value can represent either
* average received power or OMA depending upon how bit 3 of byte 92 (A0h)
* is set. Represented as a 16 bit unsigned integer with the power defined
* as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a
* total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is
* dependent upon the exact optical wavelength. For the vendor specified
* wavelength, accuracy shall be better than 3dB over specified temperature
* and voltage.
*/
uint8_t curr_rx_power[8];
/* [Prop]: wavelength
* [Desc]: Wavelength or Copper Cable Attenuation
* [Note]: (Following is info from SFF-8636)
* For optical free side devices, this parameter identifies the nominal
* transmitter output wavelength at room temperature. This parameter is a
* 16-bit hex value with Byte 186 as high order byte and Byte 187 as low
* order byte. The laser wavelength is equal to the 16-bit integer value
* divided by 20 in nm (units of 0.05 nm). This resolution should be adequate
* to cover all relevant wavelengths yet provide enough resolution for all
* expected DWDM applications. For accurate representation of controlled
* wavelength applications, this value should represent the center of the
* guaranteed wavelength range. If the free side device is identified as
* copper cable these registers will be used to define the cable attenuation.
* An indication of 0 dB attenuation refers to the case where the attenuation
* is not known or is unavailable.
* Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB.
* Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB.
*/
uint8_t wavelength[2];
/* [Prop]: Amplitude control
* [Desc]: Amplitude control
* [Note]: QSFP28 => SFF-8636 03H Byte-238/239
*/
uint8_t rx_am[2];
/* [Prop]: Emphasis control
* [Desc]: Emphasis control
* [Note]: SFP+/28 => SFF-8472 A2H Byte-115
* QSFP28 => SFF-8636 03H Byte-236/237
*/
uint8_t rx_em[2];
/* [Prop]: Soft Rx LOS
* [Desc]: Soft Rx LOS which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 3:
* - Bit 0: L-Rx1 LOS
* - Bit 1: L-Rx2 LOS
* - Bit 2: L-Rx3 LOS
* - Bit 3: L-Rx4 LOS
*/
uint8_t rx_los;
/* [Prop]: Soft Tx Disable
* [Desc]: Soft Tx Disable which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 86:
* - Bit 0: Tx1 Disable
* - Bit 1: Tx2 Disable
* - Bit 2: Tx3 Disable
* - Bit 3: Tx4 Disable
*/
uint8_t tx_disable;
/* [Prop]: Soft Tx Fault
* [Desc]: Soft Tx Fault which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 86:
* - Bit 0: Tx1 Fault
* - Bit 1: Tx2 Fault
* - Bit 2: Tx3 Fault
* - Bit 3: Tx4 Fault
*/
uint8_t tx_fault;
/* [Prop]: Transceiver EQUALIZATION
* [Desc]: Transceiver EQUALIZATION
* [Note]: SFP+/28 => SFF-8472 A2H Byte-114
* QSFP28 => SFF-8636 03H Byte-234/235
*/
uint8_t tx_eq[2];
/* [Prop]: OPTION VALUES
* [Desc]: The bits in the option field shall specify the options implemented in the transceiver.
* [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65
* QSFP+/28 => SFF-8636 00H Byte-193/195
*/
uint8_t option[3];
uint8_t eeprom[256];
/* ========== Object private property ==========
*/
struct device *transvr_dev_p;
struct eeprom_map_s *eeprom_map_p;
struct i2c_client *i2c_client_p;
struct ioexp_obj_s *ioexp_obj_p;
struct transvr_worker_s *worker_p;
struct mutex lock;
char swp_name[32];
int auto_config;
int auto_tx_disable;
int chan_id;
int chipset_type;
int curr_page;
int info;
int ioexp_virt_offset;
int lane_id[8];
int layout;
int mode;
int retry;
int state;
int temp;
int type;
/* ========== Object public functions ==========
*/
int (*get_id)(struct transvr_obj_s *self);
int (*get_eeprom)(struct transvr_obj_s *self, char *buf_p);
int (*get_ext_id)(struct transvr_obj_s *self);
int (*get_connector)(struct transvr_obj_s *self);
int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p);
int (*get_power_cls)(struct transvr_obj_s *self);
int (*get_br)(struct transvr_obj_s *self);
int (*get_len_sm)(struct transvr_obj_s *self);
int (*get_len_smf)(struct transvr_obj_s *self);
int (*get_len_om1)(struct transvr_obj_s *self);
int (*get_len_om2)(struct transvr_obj_s *self);
int (*get_len_om3)(struct transvr_obj_s *self);
int (*get_len_om4)(struct transvr_obj_s *self);
int (*get_comp_rev)(struct transvr_obj_s *self);
int (*get_comp_eth_1)(struct transvr_obj_s *self);
int (*get_comp_eth_10)(struct transvr_obj_s *self);
int (*get_comp_eth_10_40)(struct transvr_obj_s *self);
int (*get_comp_extend)(struct transvr_obj_s *self);
int (*get_cdr)(struct transvr_obj_s *self);
int (*get_rate_id)(struct transvr_obj_s *self);
int (*get_soft_rs0)(struct transvr_obj_s *self);
int (*get_soft_rs1)(struct transvr_obj_s *self);
int (*get_info)(struct transvr_obj_s *self);
int (*get_if_type)(struct transvr_obj_s *self, char *buf_p);
int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p);
int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p);
int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p);
int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p);
int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p);
int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p);
int (*set_cdr)(struct transvr_obj_s *self, int input_val);
int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val);
int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val);
int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val);
int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val);
int (*set_tx_eq)(struct transvr_obj_s *self, int input_val);
int (*set_rx_am)(struct transvr_obj_s *self, int input_val);
int (*set_rx_em)(struct transvr_obj_s *self, int input_val);
/* ========== Object private functions ==========
*/
int (*init)(struct transvr_obj_s *self);
int (*clean)(struct transvr_obj_s *self);
int (*check)(struct transvr_obj_s *self);
int (*update_all)(struct transvr_obj_s *self, int show_err);
int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name);
int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name);
int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action);
int (*dump_all)(struct transvr_obj_s* self);
};
/* For AVL Mapping */
struct transvr_avl_s {
char vendor_name[32];
char vendor_pn[32];
int (*init)(struct transvr_obj_s *self);
};
/* Worker for long term task of transceiver */
struct transvr_worker_s {
/* Task Parameter */
struct transvr_obj_s *transvr_p;
struct transvr_worker_s *next_p;
struct transvr_worker_s *pre_p;
unsigned long trigger_time;
char func_name[64];
int retry;
int state;
/* Task private data */
void *p_data;
/* Call back function */
int (*main_task)(struct transvr_worker_s *task);
int (*post_task)(struct transvr_worker_s *task);
};
struct transvr_obj_s *
create_transvr_obj(char *swp_name,
int chan_id,
struct ioexp_obj_s *ioexp_obj_p,
int ioexp_virt_offset,
int transvr_type,
int chipset_type,
int run_mode);
void lock_transvr_obj(struct transvr_obj_s *self);
void unlock_transvr_obj(struct transvr_obj_s *self);
int isolate_transvr_obj(struct transvr_obj_s *self);
int resync_channel_tier_2(struct transvr_obj_s *self);
void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg);
#endif /* TRANSCEIVER_H */

View File

@@ -0,0 +1,45 @@
#include "x86_64_inventec_d7032q28b_int.h"
#if x86_64_inventec_d7032q28b_CONFIG_INCLUDE_DEBUG == 1
#include <unistd.h>
static char help__[] =
"Usage: debug [options]\n"
" -c CPLD Versions\n"
" -h Help\n"
;
int
x86_64_inventec_d7032q28b_debug_main(int argc, char* argv[])
{
int c = 0;
int help = 0;
int rv = 0;
while( (c = getopt(argc, argv, "ch")) != -1) {
switch(c)
{
case 'c': c = 1; break;
case 'h': help = 1; rv = 0; break;
default: help = 1; rv = 1; break;
}
}
if(help || argc == 1) {
printf("%s", help__);
return rv;
}
if(c) {
printf("Not implemented.\n");
}
return 0;
}
#endif

View File

@@ -1,36 +1,21 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* fani.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Fan Platform Implementation Defaults.
*
***********************************************************/
#include <stdlib.h>
#include <onlplib/file.h>
#include <onlp/platformi/fani.h>
#include <onlplib/mmap.h>
#include <fcntl.h>
#include "platform_lib.h"
#define PREFIX_PATH_ON_MAIN_BOARD "/sys/bus/i2c/devices/2-0066/"
#define PREFIX_PATH_ON_PSU "/sys/bus/i2c/devices/"
#define FAN_GPI_ON_MAIN_BOARD INV_PSOC_PREFIX"/fan_gpi"
#define MAX_FAN_SPEED 18000
#define MAX_PSU_FAN_SPEED 25500
@@ -38,41 +23,40 @@
#define PROJECT_NAME
#define LEN_FILE_NAME 80
#define FAN_RESERVED 0
#define FAN_1_ON_MAIN_BOARD 1
#define FAN_2_ON_MAIN_BOARD 2
#define FAN_3_ON_MAIN_BOARD 3
#define FAN_4_ON_MAIN_BOARD 4
#define FAN_5_ON_MAIN_BOARD 5
#define FAN_6_ON_MAIN_BOARD 6
#define FAN_1_ON_PSU1 7
#define FAN_1_ON_PSU2 8
enum fan_id {
FAN_1_ON_FAN_BOARD = 1,
FAN_2_ON_FAN_BOARD,
FAN_3_ON_FAN_BOARD,
FAN_4_ON_FAN_BOARD,
FAN_5_ON_FAN_BOARD,
FAN_1_ON_PSU_1,
FAN_1_ON_PSU_2,
FAN_RESERVED,
FAN_1_ON_MAIN_BOARD,
FAN_2_ON_MAIN_BOARD,
FAN_3_ON_MAIN_BOARD,
FAN_4_ON_MAIN_BOARD,
FAN_5_ON_MAIN_BOARD,
FAN_6_ON_MAIN_BOARD,
FAN_7_ON_MAIN_BOARD,
FAN_8_ON_MAIN_BOARD,
FAN_1_ON_PSU1,
FAN_1_ON_PSU2,
};
#define _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) \
{ #prj"fan"#id"_present", #prj"fan"#id"_fault", #prj"fan"#id"_front_speed_rpm", \
#prj"fan"#id"_direction", #prj"fan_duty_cycle_percentage", #prj"fan"#id"_rear_speed_rpm" }
#define MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id)
#define MAKE_FAN_PATH_ON_PSU(folder) \
{"", #folder"/psu_fan1_fault", #folder"/psu_fan1_speed_rpm", \
"", #folder"/psu_fan1_duty_cycle_percentage", "" }
static char* devfiles__[CHASSIS_FAN_COUNT+1] = /* must map with onlp_thermal_id */
{
"reserved",
INV_PSOC_PREFIX"/fan1_input",
INV_PSOC_PREFIX"/fan2_input",
INV_PSOC_PREFIX"/fan3_input",
INV_PSOC_PREFIX"/fan4_input",
INV_PSOC_PREFIX"/fan5_input",
INV_PSOC_PREFIX"/fan6_input",
INV_PSOC_PREFIX"/fan7_input",
INV_PSOC_PREFIX"/fan8_input",
INV_PSOC_PREFIX"/rpm_psu1",
INV_PSOC_PREFIX"/rpm_psu2",
};
#define MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(id) \
{ \
{ ONLP_FAN_ID_CREATE(FAN_##id##_ON_MAIN_BOARD), "Chassis Fan "#id, 0 }, \
0x0, \
(ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
(ONLP_FAN_CAPS_F2B | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
@@ -82,7 +66,7 @@ enum fan_id {
{ \
{ ONLP_FAN_ID_CREATE(FAN_##fan_id##_ON_PSU##psu_id), "Chassis PSU-"#psu_id " Fan "#fan_id, 0 }, \
0x0, \
(ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
(ONLP_FAN_CAPS_F2B | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
@@ -97,6 +81,8 @@ onlp_fan_info_t linfo[] = {
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(4),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(5),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(6),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(7),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(8),
MAKE_FAN_INFO_NODE_ON_PSU(1,1),
MAKE_FAN_INFO_NODE_ON_PSU(2,1),
};
@@ -108,78 +94,41 @@ onlp_fan_info_t linfo[] = {
} \
} while(0)
static int
_onlp_fani_info_get_fan(int fid, onlp_fan_info_t* info)
{
int value, ret;
int value, ret;
char vstr[32], *vstrp = vstr, **vp = &vstrp;
/* get fan present status
*/
ret = onlp_file_read_int(&value, "%s""fan%d_present", FAN_BOARD_PATH, fid);
memset(vstr, 0, 32);
/* get fan present status */
ret = onlp_file_read_str(vp, FAN_GPI_ON_MAIN_BOARD);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
sscanf(*vp, "%x", &value);
if (value & (1 << (fid-1))) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
else {
info->status |= ONLP_FAN_STATUS_PRESENT;
info->status |= ONLP_FAN_STATUS_F2B;
}
if (value == 0) {
return ONLP_STATUS_OK;
}
info->status |= ONLP_FAN_STATUS_PRESENT;
/* get fan fault status (turn on when any one fails)
*/
ret = onlp_file_read_int(&value, "%s""fan%d_fault", FAN_BOARD_PATH, fid);
/* get front fan speed */
memset(vstr, 0, 32);
ret = onlp_file_read_str(vp, devfiles__[fid]);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
sscanf(*vp, "%d", &value);
info->rpm = value;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
if (value > 0) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
snprintf(info->model, ONLP_CONFIG_INFO_STR_MAX, "NA");
snprintf(info->serial, ONLP_CONFIG_INFO_STR_MAX, "NA");
/* get fan direction (both : the same)
*/
ret = onlp_file_read_int(&value, "%s""fan%d_direction", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->status |= value ? ONLP_FAN_STATUS_B2F : ONLP_FAN_STATUS_F2B;
/* get front fan speed
*/
ret = onlp_file_read_int(&value, "%s""fan%d_front_speed_rpm", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->rpm = value;
/* get rear fan speed
*/
ret = onlp_file_read_int(&value, "%s""fan%d_rear_speed_rpm", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
/* take the min value from front/rear fan speed
*/
if (info->rpm > value) {
info->rpm = value;
}
/* get speed percentage from rpm
*/
ret = onlp_file_read_int(&value, "%s""fan_max_speed_rpm", FAN_BOARD_PATH);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->percentage = (info->rpm * 100)/value;
return ONLP_STATUS_OK;
return ONLP_STATUS_OK;
}
@@ -212,29 +161,27 @@ _onlp_get_fan_direction_on_psu(void)
static int
_onlp_fani_info_get_fan_on_psu(int pid, onlp_fan_info_t* info)
_onlp_fani_info_get_fan_on_psu(int fid, onlp_fan_info_t* info)
{
int val = 0;
int value, ret;
char vstr[32], *vstrp = vstr, **vp = &vstrp;
info->status |= ONLP_FAN_STATUS_PRESENT;
info->status |= ONLP_FAN_STATUS_PRESENT;
info->status |= ONLP_FAN_STATUS_F2B;
/* get fan direction
*/
/* get fan direction */
info->status |= _onlp_get_fan_direction_on_psu();
/* get fan fault status
*/
if (psu_pmbus_info_get(pid, "psu_fan1_fault", &val) == ONLP_STATUS_OK) {
info->status |= (val > 0) ? ONLP_FAN_STATUS_FAILED : 0;
/* get front fan speed */
memset(vstr, 0, 32);
ret = onlp_file_read_str(vp, devfiles__[fid]);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
/* get fan speed
*/
if (psu_pmbus_info_get(pid, "psu_fan1_speed_rpm", &val) == ONLP_STATUS_OK) {
info->rpm = val;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
}
sscanf(*vp, "%d", &value);
info->rpm = value;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
info->status |= (value == 0) ? ONLP_FAN_STATUS_FAILED : 0;
return ONLP_STATUS_OK;
}
@@ -260,7 +207,7 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
switch (local_id)
{
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU2:
rc = _onlp_fani_info_get_fan_on_psu(local_id, info);
break;
@@ -270,7 +217,9 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
case FAN_4_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
rc =_onlp_fani_info_get_fan(local_id, info);
case FAN_7_ON_MAIN_BOARD:
case FAN_8_ON_MAIN_BOARD:
rc = _onlp_fani_info_get_fan(local_id, info);
break;
default:
rc = ONLP_STATUS_E_INVALID;
@@ -305,15 +254,18 @@ onlp_fani_percentage_set(onlp_oid_t id, int p)
switch (fid)
{
case FAN_1_ON_PSU_1:
return psu_pmbus_info_set(PSU1_ID, "psu_fan1_duty_cycle_percentage", p);
case FAN_1_ON_PSU_2:
return psu_pmbus_info_set(PSU2_ID, "psu_fan1_duty_cycle_percentage", p);
case FAN_1_ON_FAN_BOARD:
case FAN_2_ON_FAN_BOARD:
case FAN_3_ON_FAN_BOARD:
case FAN_4_ON_FAN_BOARD:
case FAN_5_ON_FAN_BOARD:
case FAN_1_ON_PSU1:
return psu_pmbus_info_set(PSU1_ID, "rpm_psu", p);
case FAN_1_ON_PSU2:
return psu_pmbus_info_set(PSU2_ID, "rpm_psu", p);
case FAN_1_ON_MAIN_BOARD:
case FAN_2_ON_MAIN_BOARD:
case FAN_3_ON_MAIN_BOARD:
case FAN_4_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
case FAN_7_ON_MAIN_BOARD:
case FAN_8_ON_MAIN_BOARD:
path = FAN_NODE(fan_duty_cycle_percentage);
break;
default:

View File

@@ -1,38 +1,21 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* ledi.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/ledi.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include "platform_lib.h"
#define prefix_path "/sys/class/leds/inventec_d7032q28b_led::"
#define filename "brightness"
#define VALIDATE(_id) \
@@ -42,18 +25,27 @@
} \
} while(0)
/* LED related data
*/
/* LED related data */
enum onlp_led_id
{
LED_RESERVED = 0,
LED_DIAG,
LED_LOC,
LED_FAN,
LED_PSU1,
LED_PSU2
LED_SYS,
LED_FAN1,
LED_FAN2,
LED_FAN3,
LED_FAN4
};
static char* devfiles__[CHASSIS_LED_COUNT+1] = /* must map with onlp_thermal_id */
{
"reserved",
INV_CPLD_PREFIX"/%s_led",
INV_PSOC_PREFIX"/fan_led_%s1",
INV_PSOC_PREFIX"/fan_led_%s2",
INV_PSOC_PREFIX"/fan_led_%s3",
INV_PSOC_PREFIX"/fan_led_%s4",
};
enum led_light_mode {
LED_MODE_OFF = 0,
LED_MODE_GREEN,
@@ -75,15 +67,14 @@ typedef struct led_light_mode_map {
} led_light_mode_map_t;
led_light_mode_map_t led_map[] = {
{LED_DIAG, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_DIAG, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_DIAG, LED_MODE_AMBER, ONLP_LED_MODE_ORANGE},
{LED_DIAG, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_LOC, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_LOC, LED_MODE_BLUE, ONLP_LED_MODE_BLUE},
{LED_FAN, LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_PSU1, LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_PSU2, LED_MODE_AUTO, ONLP_LED_MODE_AUTO}
{LED_SYS, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_SYS, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_SYS, LED_MODE_AMBER, ONLP_LED_MODE_ORANGE},
{LED_SYS, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_FAN1,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_FAN2,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_FAN3,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_FAN4,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
};
static char last_path[][10] = /* must map with onlp_led_id */
@@ -103,47 +94,37 @@ static onlp_led_info_t linfo[] =
{
{ }, /* Not used */
{
{ ONLP_LED_ID_CREATE(LED_DIAG), "Chassis LED 1 (DIAG LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_SYS), "Chassis LED (SYSTEM LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED | ONLP_LED_CAPS_ORANGE,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_LOC), "Chassis LED 2 (LOC LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN1), "Fan LED 1 (FAN1 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_BLUE,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_FAN), "Chassis LED 3 (FAN LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN2), "Fan LED 2 (FAN2 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_AUTO,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_PSU1), "Chassis LED 4 (PSU1 LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN3), "Fan LED 3 (FAN3 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_AUTO,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_PSU2), "Chassis LED 4 (PSU2 LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN4), "Fan LED 4 (FAN4 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_AUTO,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
};
static int driver_to_onlp_led_mode(enum onlp_led_id id, enum led_light_mode driver_led_mode)
{
int i, nsize = sizeof(led_map)/sizeof(led_map[0]);
for (i = 0; i < nsize; i++)
{
if (id == led_map[i].id && driver_led_mode == led_map[i].driver_led_mode)
{
return led_map[i].onlp_led_mode;
}
}
return 0;
}
static int onlp_to_driver_led_mode(enum onlp_led_id id, onlp_led_mode_t onlp_led_mode)
{
int i, nsize = sizeof(led_map)/sizeof(led_map[0]);
@@ -168,41 +149,113 @@ onlp_ledi_init(void)
/*
* Diag LED Off
*/
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_DIAG), ONLP_LED_MODE_OFF);
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_SYS), ONLP_LED_MODE_OFF);
return ONLP_STATUS_OK;
}
int onlp_chassis_led_read(char *pathp, char *buf, size_t len)
{
FILE * fp;
fp = fopen (pathp, "r");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
if( fgets (buf, len, fp) == NULL ) {
perror("Error fgets operation");
}
fclose(fp);
return(0);
}
int
onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
{
int local_id;
char data[2] = {0};
char fullpath[50] = {0};
int local_id, gret = 0, rret = 0;
char fullpath_grn[50] = {0};
char fullpath_red[50] = {0};
int gvalue = 0, rvalue = 0;
char buf[32] = {0};
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
/* get fullpath */
sprintf(fullpath, "%s%s/%s", prefix_path, last_path[local_id], filename);
switch (local_id) {
case LED_SYS:
sprintf(fullpath_grn, devfiles__[local_id], "grn");
sprintf(fullpath_red, devfiles__[local_id], "red");
/* Set LED mode */
gret = onlp_chassis_led_read(fullpath_grn, buf, 32);
if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3' || buf[0] == '7') {
gvalue = 1;
}
rret = onlp_chassis_led_read(fullpath_red, buf, 32);
if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3' || buf[0] == '7') {
rvalue = 1;
}
if (gret < 0 && rret < 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
gvalue = -1;
rvalue = -1;
}
break;
case LED_FAN1:
case LED_FAN2:
case LED_FAN3:
case LED_FAN4:
sprintf(fullpath_grn, devfiles__[local_id], "grn");
sprintf(fullpath_red, devfiles__[local_id], "red");
/* Set LED mode */
if (onlp_file_read_int(&gvalue, fullpath_grn) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
gvalue = 0;
}
if (onlp_file_read_int(&rvalue, fullpath_red) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
rvalue = 0;
}
break;
default:
DEBUG_PRINT("%s(%d) Invalid led id %d\r\n", __FUNCTION__, __LINE__, local_id);
gvalue = -1;
rvalue = -1;
break;
}
/* Set the onlp_oid_hdr_t and capabilities */
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[ONLP_OID_ID_GET(id)];
/* Set LED mode */
if (onlp_file_read_string(fullpath, data, sizeof(data), 0) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
return ONLP_STATUS_E_INTERNAL;
if (gvalue == 1 && rvalue == 0) {
info->mode = ONLP_LED_MODE_GREEN;
info->status |= ONLP_LED_STATUS_ON;
}
info->mode = driver_to_onlp_led_mode(local_id, atoi(data));
/* Set the on/off status */
if (info->mode != ONLP_LED_MODE_OFF) {
info->status |= ONLP_LED_STATUS_ON;
else
if (gvalue == 0 && rvalue == 1) {
info->mode = ONLP_LED_MODE_RED;
info->status |= ONLP_LED_STATUS_ON;
}
else
if (gvalue == 1 && rvalue == 1) {
info->mode = ONLP_LED_MODE_ORANGE;
info->status |= ONLP_LED_STATUS_ON;
}
else
if (gvalue == 0 && rvalue == 0) {
info->mode = ONLP_LED_MODE_OFF;
info->status |= ONLP_LED_STATUS_ON;
}
else {
info->mode = ONLP_LED_MODE_OFF;
info->status |= ONLP_LED_STATUS_FAILED;
}
return ONLP_STATUS_OK;
}
@@ -242,7 +295,20 @@ onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
sprintf(fullpath, "%s%s/%s", prefix_path, last_path[local_id], filename);
switch (local_id) {
case LED_SYS:
sprintf(fullpath, "%s%s/%s", INV_CPLD_PREFIX, last_path[local_id], filename);
break;
case LED_FAN1:
case LED_FAN2:
case LED_FAN3:
case LED_FAN4:
sprintf(fullpath, "%s%s/%s", INV_PSOC_PREFIX, last_path[local_id], filename);
break;
default:
DEBUG_PRINT("%s(%d) Invalid led id %d\r\n", __FUNCTION__, __LINE__, local_id);
return ONLP_STATUS_E_INTERNAL;
}
if (onlp_file_write_int(onlp_to_driver_led_mode(local_id, mode), fullpath, NULL) != 0)
{

View File

@@ -1,27 +1,10 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* platform_lib.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <sys/mman.h>
#include <errno.h>
@@ -152,10 +135,14 @@ int psu_pmbus_info_get(int id, char *node, int *value)
*value = 0;
if (PSU1_ID == id) {
ret = onlp_file_read_int(value, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
ret = onlp_file_read_int(value, "%s%s%d", PSU1_AC_PMBUS_PREFIX, node, PSU1_ID);
}
else
if (PSU2_ID == id) {
ret = onlp_file_read_int(value, "%s%s%d", PSU2_AC_PMBUS_PREFIX, node, PSU2_ID);
}
else {
ret = onlp_file_read_int(value, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
return ONLP_STATUS_E_INTERNAL;
}
if (ret < 0) {
@@ -171,10 +158,10 @@ int psu_pmbus_info_set(int id, char *node, int value)
switch (id) {
case PSU1_ID:
sprintf(path, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
sprintf(path, "%s%s%d", PSU1_AC_PMBUS_PREFIX, node, PSU1_ID);
break;
case PSU2_ID:
sprintf(path, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
sprintf(path, "%s%s%d", PSU2_AC_PMBUS_PREFIX, node, PSU2_ID);
break;
default:
return ONLP_STATUS_E_UNSUPPORTED;

View File

@@ -1,61 +1,54 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* platform_lib.h
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __PLATFORM_LIB_H__
#define __PLATFORM_LIB_H__
#include "x86_64_inventec_d7032q28b_log.h"
#define CHASSIS_FAN_COUNT 6
#define CHASSIS_THERMAL_COUNT 5
#define ONLP_NODE_MAX_INT_LEN (8)
#define ONLP_NODE_MAX_PATH_LEN (64)
#define PSU1_ID 1
#define PSU2_ID 2
#define CHASSIS_PSU_COUNT (2)
#define CHASSIS_LED_COUNT (5)
#define CHASSIS_FAN_COUNT (10)
#define CHASSIS_SFP_COUNT (32)
#define CHASSIS_THERMAL_COUNT (11)
#define PSU1_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/11-005b/"
#define PSU2_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/10-0058/"
#define INV_CPLD_COUNT (1)
#define INV_CPLD_PREFIX "/sys/bus/i2c/devices/0-0055/"
#define INV_PSOC_PREFIX "/sys/bus/i2c/devices/0-0066/"
#define INV_EPRM_PREFIX "/sys/bus/i2c/devices/0-0053/"
#define INV_CTMP_PREFIX "/sys/devices/platform/coretemp.0/hwmon/hwmon0/"
/*
* Definitions of Chassis EEPROM
*/
#define EEPROM_NODE(node) INV_EPRM_PREFIX#node
/*
* Definitions of PSU device
*/
enum onlp_psu_id
{
PSU_RESERVED = 0,
PSU1_ID,
PSU2_ID
};
#define PSU1_AC_PMBUS_PREFIX INV_PSOC_PREFIX
#define PSU2_AC_PMBUS_PREFIX INV_PSOC_PREFIX
#define PSU1_AC_PMBUS_NODE(node) PSU1_AC_PMBUS_PREFIX#node
#define PSU2_AC_PMBUS_NODE(node) PSU2_AC_PMBUS_PREFIX#node
#define PSU1_AC_HWMON_PREFIX "/sys/bus/i2c/devices/11-0053/"
#define PSU2_AC_HWMON_PREFIX "/sys/bus/i2c/devices/10-0050/"
#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node
#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node
#define FAN_BOARD_PATH "/sys/devices/platform/fan/"
#define FAN_NODE(node) FAN_BOARD_PATH#node
#define IDPROM_PATH "/sys/class/i2c-adapter/i2c-1/1-0057/eeprom"
int onlp_file_read_binary(char *filename, char *buffer, int buf_size, int data_len);
int onlp_file_read_string(char *filename, char *buffer, int buf_size, int data_len);
int psu_pmbus_info_get(int id, char *node, int *value);
int psu_pmbus_info_set(int id, char *node, int value);
#define PSU1_AC_HWMON_PREFIX INV_CPLD_PREFIX
#define PSU2_AC_HWMON_PREFIX INV_CPLD_PREFIX
typedef enum psu_type {
PSU_TYPE_UNKNOWN,
@@ -70,6 +63,24 @@ typedef enum psu_type {
psu_type_t get_psu_type(int id, char* modelname, int modelname_len);
#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node
#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node
/*
* Definitions of FAN device
*/
#define FAN_BOARD_PATH INV_PSOC_PREFIX
#define FAN_NODE(node) FAN_BOARD_PATH#node
/*
* Prototypes
*/
int onlp_file_read_binary(char *filename, char *buffer, int buf_size, int data_len);
int onlp_file_read_string(char *filename, char *buffer, int buf_size, int data_len);
int psu_pmbus_info_get(int id, char *node, int *value);
int psu_pmbus_info_set(int id, char *node, int value);
#define DEBUG_MODE 0
#if (DEBUG_MODE == 1)

View File

@@ -1,40 +1,24 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* psui.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/psui.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "platform_lib.h"
#define PSU_STATUS_PRESENT 1
#define PSU_STATUS_POWER_GOOD 1
#define PSU_NODE_MAX_INT_LEN 8
#define PSU_NODE_MAX_PATH_LEN 64
#define PSU_STATUS_PRESENT (0)
#define PSU_STATUS_POWER_GOOD (1)
#define PSU_STATUS_UNPOWERED (2)
#define PSU_STATUS_FAULT (4)
#define PSU_STATUS_UNINSTALLED (7)
#define VALIDATE(_id) \
do { \
@@ -43,55 +27,50 @@
} \
} while(0)
static char* status_devfiles__[CHASSIS_PSU_COUNT+1] = /* must map with onlp_psu_id */
{
"reserved",
INV_CPLD_PREFIX"/psu0",
INV_CPLD_PREFIX"/psu1",
};
static char* module_devfiles__[CHASSIS_PSU_COUNT+1] = /* must map with onlp_psu_id */
{
"reserved",
INV_PSOC_PREFIX"/psoc_psu1_%s",
INV_PSOC_PREFIX"/psoc_psu2_%s",
};
static int
psu_status_info_get(int id, char *node, int *value)
{
int ret = 0;
char node_path[PSU_NODE_MAX_PATH_LEN] = {0};
char node_path[ONLP_NODE_MAX_PATH_LEN] = {0};
char vstr[32], *vstrp = vstr, **vp = &vstrp;
*value = 0;
if (PSU1_ID == id) {
sprintf(node_path, "%s%s", PSU1_AC_HWMON_PREFIX, node);
sprintf(node_path, status_devfiles__[id]);
}
else if (PSU2_ID == id) {
sprintf(node_path, "%s%s", PSU2_AC_HWMON_PREFIX, node);
sprintf(node_path, status_devfiles__[id]);
}
ret = onlp_file_read_int(value, node_path);
ret = onlp_file_read_str(vp, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
return ret;
if (!isdigit(*vstrp)) {
return ONLP_STATUS_E_INTERNAL;
}
*value = *vstrp - '0';
return ONLP_STATUS_OK;
}
static int
psu_ym2651_pmbus_info_get(int id, char *node, int *value)
{
int ret = 0;
char node_path[PSU_NODE_MAX_PATH_LEN] = {0};
*value = 0;
if (PSU1_ID == id) {
sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
}
else {
sprintf(node_path, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
}
ret = onlp_file_read_int(value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
return ret;
}
int
onlp_psui_init(void)
@@ -100,84 +79,73 @@ onlp_psui_init(void)
}
static int
psu_ym2651_info_get(onlp_psu_info_t* info)
psu_module_info_get(int id, onlp_psu_info_t* info)
{
int val = 0;
int index = ONLP_OID_ID_GET(info->hdr.id);
int ret = 0;
char node_path[ONLP_NODE_MAX_PATH_LEN] = {0};
int value = 0;
if (info->status & ONLP_PSU_STATUS_FAILED) {
return ONLP_STATUS_OK;
info->caps |= ONLP_PSU_CAPS_DC12;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "vout");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mvout = value;
info->caps |= ONLP_PSU_CAPS_VOUT;
/* Set the associated oid_table */
info->hdr.coids[0] = ONLP_FAN_ID_CREATE(index + CHASSIS_FAN_COUNT);
info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(index + CHASSIS_THERMAL_COUNT);
/* Read voltage, current and power */
if (psu_ym2651_pmbus_info_get(index, "psu_v_out", &val) == 0) {
info->mvout = val;
info->caps |= ONLP_PSU_CAPS_VOUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "iout");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->miout = value;
info->caps |= ONLP_PSU_CAPS_IOUT;
if (psu_ym2651_pmbus_info_get(index, "psu_i_out", &val) == 0) {
info->miout = val;
info->caps |= ONLP_PSU_CAPS_IOUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "pout");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mpout = value;
info->caps |= ONLP_PSU_CAPS_POUT;
if (psu_ym2651_pmbus_info_get(index, "psu_p_out", &val) == 0) {
info->mpout = val;
info->caps |= ONLP_PSU_CAPS_POUT;
}
return ONLP_STATUS_OK;
}
#include <onlplib/i2c.h>
#define DC12V_750_REG_TO_CURRENT(low, high) (((low << 4 | high >> 4) * 20 * 1000) / 754)
#define DC12V_750_REG_TO_VOLTAGE(low, high) ((low << 4 | high >> 4) * 25)
static int
psu_dc12v_750_info_get(onlp_psu_info_t* info)
{
int pid = ONLP_OID_ID_GET(info->hdr.id);
int bus = (PSU1_ID == pid) ? 11 : 10;
int iout_low, iout_high;
int vout_low, vout_high;
/* Set capability
*/
info->caps = ONLP_PSU_CAPS_DC12;
if (info->status & ONLP_PSU_STATUS_FAILED) {
return ONLP_STATUS_OK;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "vin");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mvin = value;
info->caps |= ONLP_PSU_CAPS_VIN;
/* Get current
*/
iout_low = onlp_i2c_readb(bus, 0x6f, 0x0, ONLP_I2C_F_FORCE);
iout_high = onlp_i2c_readb(bus, 0x6f, 0x1, ONLP_I2C_F_FORCE);
if ((iout_low >= 0) && (iout_high >= 0)) {
info->miout = DC12V_750_REG_TO_CURRENT(iout_low, iout_high);
info->caps |= ONLP_PSU_CAPS_IOUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "iin");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->miin = value;
info->caps |= ONLP_PSU_CAPS_IIN;
/* Get voltage
*/
vout_low = onlp_i2c_readb(bus, 0x6f, 0x2, ONLP_I2C_F_FORCE);
vout_high = onlp_i2c_readb(bus, 0x6f, 0x3, ONLP_I2C_F_FORCE);
if ((vout_low >= 0) && (vout_high >= 0)) {
info->mvout = DC12V_750_REG_TO_VOLTAGE(vout_low, vout_high);
info->caps |= ONLP_PSU_CAPS_VOUT;
}
/* Get power based on current and voltage
*/
if ((info->caps & ONLP_PSU_CAPS_IOUT) && (info->caps & ONLP_PSU_CAPS_VOUT)) {
info->mpout = (info->miout * info->mvout) / 1000;
info->caps |= ONLP_PSU_CAPS_POUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "pin");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mpin = value;
info->caps |= ONLP_PSU_CAPS_PIN;
return ONLP_STATUS_OK;
}
@@ -202,7 +170,6 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
int val = 0;
int ret = ONLP_STATUS_OK;
int index = ONLP_OID_ID_GET(id);
psu_type_t psu_type;
VALIDATE(id);
@@ -210,63 +177,27 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
*info = pinfo[index]; /* Set the onlp_oid_hdr_t */
/* Get the present state */
if (psu_status_info_get(index, "psu_present", &val) != 0) {
if ((ret = psu_status_info_get(index, "psu", &val)) == ONLP_STATUS_E_INTERNAL) {
printf("Unable to read PSU(%d) node(psu_present)\r\n", index);
return ret;
}
if (val != PSU_STATUS_PRESENT) {
info->status &= ~ONLP_PSU_STATUS_PRESENT;
return ONLP_STATUS_OK;
if (val == 0) {
info->status = ONLP_PSU_STATUS_PRESENT;
}
info->status |= ONLP_PSU_STATUS_PRESENT;
/* Get power good status */
if (psu_status_info_get(index, "psu_power_good", &val) != 0) {
printf("Unable to read PSU(%d) node(psu_power_good)\r\n", index);
else
if (val == 1) {
info->status = ONLP_PSU_STATUS_UNPLUGGED;
return ret;
}
else {
info->status = ONLP_PSU_STATUS_FAILED;
return ret;
}
if (val != PSU_STATUS_POWER_GOOD) {
info->status |= ONLP_PSU_STATUS_FAILED;
}
/* Get PSU type
*/
psu_type = get_psu_type(index, info->model, sizeof(info->model));
switch (psu_type) {
case PSU_TYPE_AC_F2B:
case PSU_TYPE_AC_B2F:
info->caps = ONLP_PSU_CAPS_AC;
ret = psu_ym2651_info_get(info);
break;
case PSU_TYPE_DC_48V_F2B:
case PSU_TYPE_DC_48V_B2F:
info->caps = ONLP_PSU_CAPS_DC48;
ret = psu_ym2651_info_get(info);
break;
case PSU_TYPE_DC_12V_F2B:
case PSU_TYPE_DC_12V_B2F:
case PSU_TYPE_DC_12V_FANLESS:
ret = psu_dc12v_750_info_get(info);
break;
case PSU_TYPE_UNKNOWN: /* User insert a unknown PSU or unplugged.*/
info->status |= ONLP_PSU_STATUS_UNPLUGGED;
info->status &= ~ONLP_PSU_STATUS_FAILED;
ret = ONLP_STATUS_OK;
break;
default:
ret = ONLP_STATUS_E_UNSUPPORTED;
break;
if ((ret = psu_module_info_get(index, info)) != ONLP_STATUS_OK) {
printf("Unable to read PSU(%d) module information\r\n", index);
}
return ret;
}
int
onlp_psui_ioctl(onlp_oid_t pid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -1,27 +1,10 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* sfpi.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/sfpi.h>
@@ -34,19 +17,17 @@
#include <onlplib/file.h>
#include "platform_lib.h"
#define MAX_SFP_PATH 64
static char sfp_node_path[MAX_SFP_PATH] = {0};
static char sfp_node_path[ONLP_NODE_MAX_PATH_LEN] = {0};
#define MUX_START_INDEX 18
#define NUM_OF_SFP_PORT 32
#define NUM_OF_SFP_PORT (CHASSIS_SFP_COUNT)
static const int sfp_mux_index[NUM_OF_SFP_PORT] = {
4, 5, 6, 7, 9, 8, 11, 10,
0, 1, 2, 3, 12, 13, 14, 15,
16, 17, 18, 19, 28, 29, 30, 31,
20, 21, 22, 23, 24, 25, 26, 27
22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37,
6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21
};
#define FRONT_PORT_TO_MUX_INDEX(port) (sfp_mux_index[port]+MUX_START_INDEX)
#define FRONT_PORT_TO_MUX_INDEX(port) (sfp_mux_index[port])
static int
sfp_node_read_int(char *node_path, int *value, int data_len)
@@ -67,9 +48,7 @@ sfp_node_read_int(char *node_path, int *value, int data_len)
static char*
sfp_get_port_path(int port, char *node_name)
{
sprintf(sfp_node_path, "/sys/bus/i2c/devices/%d-0050/%s",
FRONT_PORT_TO_MUX_INDEX(port),
node_name);
sprintf(sfp_node_path, "/sys/class/swps/port%d/%s", port, node_name);
return sfp_node_path;
}
@@ -111,66 +90,58 @@ onlp_sfpi_is_present(int port)
* Return < 0 if error.
*/
int present;
char* path = sfp_get_port_path(port, "sfp_is_present");
char* path = sfp_get_port_path(port, "present");
if (sfp_node_read_int(path, &present, 0) != 0) {
AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
if (present == 0) {
present = 1;
}
else
if (present == 1) {
present = 0;
}
else {
AIM_LOG_ERROR("Unvalid present status %d from port(%d)\r\n",present,port);
return ONLP_STATUS_E_INTERNAL;
}
return present;
}
int
onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
{
uint32_t bytes[4];
char* path;
FILE* fp;
path = sfp_get_port_path(0, "sfp_is_present_all");
fp = fopen(path, "r");
if(fp == NULL) {
AIM_LOG_ERROR("Unable to open the sfp_is_present_all device file.");
return ONLP_STATUS_E_INTERNAL;
}
int count = fscanf(fp, "%x %x %x %x",
bytes+0,
bytes+1,
bytes+2,
bytes+3
);
fclose(fp);
if(count != AIM_ARRAYSIZE(bytes)) {
/* Likely a CPLD read timeout. */
AIM_LOG_ERROR("Unable to read all fields from the sfp_is_present_all device file.");
return ONLP_STATUS_E_INTERNAL;
}
/* Convert to 64 bit integer in port order */
int i = 0;
uint32_t presence_all = 0 ;
for(i = AIM_ARRAYSIZE(bytes)-1; i >= 0; i--) {
presence_all <<= 8;
presence_all |= bytes[i];
int port, ret;
for (port = 0; port < NUM_OF_SFP_PORT; port++) {
ret = onlp_sfpi_is_present(port);
if (ret == 1) {
presence_all |= (1<<port);
}
else
if (ret == 0) {
presence_all &= ~(1<<port);
}
else {
AIM_LOG_ERROR("Unable to read present status of port(%d).", port);
}
}
/* Populate bitmap */
for(i = 0; presence_all; i++) {
AIM_BITMAP_MOD(dst, i, (presence_all & 1));
for(port = 0; presence_all; port++) {
AIM_BITMAP_MOD(dst, port, (presence_all & 1));
presence_all >>= 1;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
char* path = sfp_get_port_path(port, "sfp_eeprom");
char* path;
int len = 0;
/*
* Read the SFP eeprom into data[]
*
@@ -178,15 +149,20 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])
* Return OK if eeprom is read
*/
memset(data, 0, 256);
if (onlp_file_read((uint8_t*)data, 256, &len, path) < 0) {
path = sfp_get_port_path(port, "eeprom");
if (onlp_file_read(&data[0], 256, &len, path) < 0) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_dom_read(int port, uint8_t data[256])
{
return onlp_sfpi_eeprom_read( port, data);
}
int
onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr)
{

View File

@@ -1,27 +1,10 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* sysi.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <unistd.h>
#include <fcntl.h>
@@ -38,19 +21,12 @@
#include "platform_lib.h"
#define NUM_OF_THERMAL_ON_MAIN_BROAD CHASSIS_THERMAL_COUNT
#define NUM_OF_FAN_ON_MAIN_BROAD CHASSIS_FAN_COUNT
#define NUM_OF_PSU_ON_MAIN_BROAD 2
#define NUM_OF_LED_ON_MAIN_BROAD 5
#define NUM_OF_CPLD INV_CPLD_COUNT
#define PREFIX_PATH_ON_CPLD_DEV "/sys/bus/i2c/devices/"
#define NUM_OF_CPLD 3
static char arr_cplddev_name[NUM_OF_CPLD][10] =
{
"4-0060",
"5-0062",
"6-0064"
};
#define NUM_OF_THERMAL_ON_MAIN_BROAD (CHASSIS_THERMAL_COUNT)
#define NUM_OF_FAN_ON_MAIN_BROAD (CHASSIS_FAN_COUNT)
#define NUM_OF_PSU_ON_MAIN_BROAD (CHASSIS_PSU_COUNT)
#define NUM_OF_LED_ON_MAIN_BROAD (CHASSIS_LED_COUNT)
const char*
onlp_sysi_platform_get(void)
@@ -62,7 +38,7 @@ int
onlp_sysi_onie_data_get(uint8_t** data, int* size)
{
uint8_t* rdata = aim_zmalloc(256);
if(onlp_file_read(rdata, 256, size, IDPROM_PATH) == ONLP_STATUS_OK) {
if(onlp_file_read(rdata, 256, size, EEPROM_NODE(eeprom)) == ONLP_STATUS_OK) {
if(*size == 256) {
*data = rdata;
return ONLP_STATUS_OK;
@@ -74,27 +50,6 @@ onlp_sysi_onie_data_get(uint8_t** data, int* size)
return ONLP_STATUS_E_INTERNAL;
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
int i, v[NUM_OF_CPLD]={0};
for (i=0; i < NUM_OF_CPLD; i++) {
v[i] = 0;
if(onlp_file_read_int(v+i, "%s%s/version", PREFIX_PATH_ON_CPLD_DEV, arr_cplddev_name[i]) < 0) {
return ONLP_STATUS_E_INTERNAL;
}
}
pi->cpld_versions = aim_fstrdup("%d.%d.%d", v[0], v[1], v[2]);
return 0;
}
void
onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
{
aim_free(pi->cpld_versions);
}
int
onlp_sysi_oids_get(onlp_oid_t* table, int max)
{
@@ -129,167 +84,27 @@ onlp_sysi_oids_get(onlp_oid_t* table, int max)
return 0;
}
typedef struct fan_ctrl_policy {
int duty_cycle;
int temp_down_adjust; /* The boundary temperature to down adjust fan speed */
int temp_up_adjust; /* The boundary temperature to up adjust fan speed */
} fan_ctrl_policy_t;
fan_ctrl_policy_t fan_ctrl_policy_f2b[] = {
{32, 0, 174000},
{38, 170000, 182000},
{50, 178000, 190000},
{63, 186000, 0}
};
fan_ctrl_policy_t fan_ctrl_policy_b2f[] = {
{32, 0, 140000},
{38, 135000, 150000},
{50, 145000, 160000},
{69, 155000, 0}
};
#define FAN_DUTY_CYCLE_MAX 100
#define FAN_SPEED_CTRL_PATH "/sys/bus/i2c/devices/2-0066/fan_duty_cycle_percentage"
/*
* For AC power Front to Back :
* * If any fan fail, please fan speed register to 15
* * The max value of Fan speed register is 9
* [LM75(48) + LM75(49) + LM75(4A)] > 174 => set Fan speed value from 4 to 5
* [LM75(48) + LM75(49) + LM75(4A)] > 182 => set Fan speed value from 5 to 7
* [LM75(48) + LM75(49) + LM75(4A)] > 190 => set Fan speed value from 7 to 9
*
* [LM75(48) + LM75(49) + LM75(4A)] < 170 => set Fan speed value from 5 to 4
* [LM75(48) + LM75(49) + LM75(4A)] < 178 => set Fan speed value from 7 to 5
* [LM75(48) + LM75(49) + LM75(4A)] < 186 => set Fan speed value from 9 to 7
*
*
* For AC power Back to Front :
* * If any fan fail, please fan speed register to 15
* * The max value of Fan speed register is 10
* [LM75(48) + LM75(49) + LM75(4A)] > 140 => set Fan speed value from 4 to 5
* [LM75(48) + LM75(49) + LM75(4A)] > 150 => set Fan speed value from 5 to 7
* [LM75(48) + LM75(49) + LM75(4A)] > 160 => set Fan speed value from 7 to 10
*
* [LM75(48) + LM75(49) + LM75(4A)] < 135 => set Fan speed value from 5 to 4
* [LM75(48) + LM75(49) + LM75(4A)] < 145 => set Fan speed value from 7 to 5
* [LM75(48) + LM75(49) + LM75(4A)] < 155 => set Fan speed value from 10 to 7
*/
int
onlp_sysi_platform_manage_fans(void)
static char *arr_cplddev_version[NUM_OF_CPLD] =
{
int i = 0, arr_size, temp;
fan_ctrl_policy_t *policy;
int cur_duty_cycle, new_duty_cycle;
onlp_thermal_info_t thermal_1, thermal_2, thermal_3;
INV_CPLD_PREFIX"/version",
};
int fd, len;
char buf[10] = {0};
/* Get each fan status
*/
for (i = 1; i <= NUM_OF_FAN_ON_MAIN_BROAD; i++)
{
onlp_fan_info_t fan_info;
if (onlp_fani_info_get(ONLP_FAN_ID_CREATE(i), &fan_info) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to get fan(%d) status\r\n", i);
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
int i, v[NUM_OF_CPLD]={0};
for (i=0; i < NUM_OF_CPLD; i++) {
v[i] = 0;
if(onlp_file_read_int(v+i, arr_cplddev_version[i]) < 0) {
return ONLP_STATUS_E_INTERNAL;
}
/* Decision 1: Set fan as full speed if any fan is failed.
*/
if (fan_info.status & ONLP_FAN_STATUS_FAILED) {
AIM_LOG_ERROR("Fan(%d) is not working, set the other fans as full speed\r\n", i);
return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
/* Decision 1.1: Set fan as full speed if any fan is not present.
*/
if (!(fan_info.status & ONLP_FAN_STATUS_PRESENT)) {
AIM_LOG_ERROR("Fan(%d) is not present, set the other fans as full speed\r\n", i);
return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
/* Get fan direction (Only get the first one since all fan direction are the same)
*/
if (i == 1) {
if (fan_info.status & ONLP_FAN_STATUS_F2B) {
policy = fan_ctrl_policy_f2b;
arr_size = AIM_ARRAYSIZE(fan_ctrl_policy_f2b);
}
else {
policy = fan_ctrl_policy_b2f;
arr_size = AIM_ARRAYSIZE(fan_ctrl_policy_b2f);
}
}
}
/* Get current fan speed
*/
fd = open(FAN_SPEED_CTRL_PATH, O_RDONLY);
if (fd == -1){
AIM_LOG_ERROR("Unable to open fan speed control node (%s)", FAN_SPEED_CTRL_PATH);
return ONLP_STATUS_E_INTERNAL;
}
len = read(fd, buf, sizeof(buf));
close(fd);
if (len <= 0) {
AIM_LOG_ERROR("Unable to read fan speed from (%s)", FAN_SPEED_CTRL_PATH);
return ONLP_STATUS_E_INTERNAL;
}
cur_duty_cycle = atoi(buf);
/* Decision 2: If no matched fan speed is found from the policy,
* use FAN_DUTY_CYCLE_MIN as default speed
*/
for (i = 0; i < arr_size; i++) {
if (policy[i].duty_cycle != cur_duty_cycle)
continue;
break;
}
if (i == arr_size) {
return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), policy[0].duty_cycle);
}
/* Get current temperature
*/
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(2), &thermal_1) != ONLP_STATUS_OK ||
onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(3), &thermal_2) != ONLP_STATUS_OK ||
onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(4), &thermal_3) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to read thermal status");
return ONLP_STATUS_E_INTERNAL;
}
temp = thermal_1.mcelsius + thermal_2.mcelsius + thermal_3.mcelsius;
/* Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature
*/
new_duty_cycle = cur_duty_cycle;
if ((temp >= policy[i].temp_up_adjust) && (i != (arr_size-1))) {
new_duty_cycle = policy[i+1].duty_cycle;
}
else if ((temp <= policy[i].temp_down_adjust) && (i != 0)) {
new_duty_cycle = policy[i-1].duty_cycle;
}
if (new_duty_cycle == cur_duty_cycle) {
/* Duty cycle does not change, just return */
return ONLP_STATUS_OK;
}
return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), new_duty_cycle);
pi->cpld_versions = aim_fstrdup("%d.%d", v[0], v[1]);
return 0;
}
int
onlp_sysi_platform_manage_leds(void)
void
onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
{
return ONLP_STATUS_E_UNSUPPORTED;
aim_free(pi->cpld_versions);
}

View File

@@ -1,23 +1,8 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* thermali.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Thermal Sensor Platform Implementation.
@@ -40,39 +25,51 @@
enum onlp_thermal_id
{
THERMAL_RESERVED = 0,
THERMAL_CPU_CORE,
THERMAL_CPU_CORE_FIRST,
THERMAL_CPU_CORE_3,
THERMAL_CPU_CORE_4,
THERMAL_CPU_CORE_LAST,
THERMAL_1_ON_MAIN_BROAD,
THERMAL_2_ON_MAIN_BROAD,
THERMAL_3_ON_MAIN_BROAD,
THERMAL_4_ON_MAIN_BROAD,
THERMAL_5_ON_MAIN_BROAD,
THERMAL_1_ON_PSU1,
THERMAL_1_ON_PSU2,
};
static char* devfiles__[] = /* must map with onlp_thermal_id */
static char* devfiles__[CHASSIS_THERMAL_COUNT+1] = /* must map with onlp_thermal_id */
{
"reserved",
NULL, /* CPU_CORE files */
"/sys/bus/i2c/devices/3-0048*temp1_input",
"/sys/bus/i2c/devices/3-0049*temp1_input",
"/sys/bus/i2c/devices/3-004a*temp1_input",
"/sys/bus/i2c/devices/3-004b*temp1_input",
"/sys/bus/i2c/devices/11-005b*psu_temp1_input",
"/sys/bus/i2c/devices/10-0058*psu_temp1_input",
INV_CTMP_PREFIX"/temp2_%s",
INV_CTMP_PREFIX"/temp3_%s",
INV_CTMP_PREFIX"/temp4_%s",
INV_CTMP_PREFIX"/temp5_%s",
INV_PSOC_PREFIX"/temp1_input",
INV_PSOC_PREFIX"/temp2_input",
INV_PSOC_PREFIX"/temp3_input",
INV_PSOC_PREFIX"/temp4_input",
INV_PSOC_PREFIX"/temp5_input",
INV_PSOC_PREFIX"/thermal_psu1",
INV_PSOC_PREFIX"/thermal_psu2",
};
static char* cpu_coretemp_files[] =
{
"/sys/devices/platform/coretemp.0*temp2_input",
"/sys/devices/platform/coretemp.0*temp3_input",
"/sys/devices/platform/coretemp.0*temp4_input",
"/sys/devices/platform/coretemp.0*temp5_input",
NULL,
};
/* Static values */
static onlp_thermal_info_t linfo[] = {
static onlp_thermal_info_t linfo[CHASSIS_THERMAL_COUNT+1] = {
{ }, /* Not used */
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE), "CPU Core", 0},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_FIRST), "CPU Core 0", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_3), "CPU Core 1", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_4), "CPU Core 2", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_LAST), "CPU Core 3", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
@@ -92,6 +89,10 @@ static onlp_thermal_info_t linfo[] = {
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BROAD), "Chassis Thermal Sensor 5", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU1), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU1_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
@@ -99,7 +100,7 @@ static onlp_thermal_info_t linfo[] = {
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU2), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU2_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
}
},
};
/*
@@ -132,10 +133,16 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[local_id];
if(local_id == THERMAL_CPU_CORE) {
int rv = onlp_file_read_int_max(&info->mcelsius, cpu_coretemp_files);
return rv;
}
if(local_id >= THERMAL_CPU_CORE_FIRST && local_id <= THERMAL_CPU_CORE_LAST) {
char desc[32], *dp = &desc[0];
int rv = onlp_file_read_str(&dp, devfiles__[local_id], "label");
if (rv > 0) {
memset (info->hdr.description, 0, ONLP_OID_DESC_SIZE);
strncpy(info->hdr.description, dp, rv);
}
/* Set the onlp_oid_hdr_t and capabilities */
return onlp_file_read_int(&info->mcelsius, devfiles__[local_id], "input");
}
return onlp_file_read_int(&info->mcelsius, devfiles__[local_id]);
}

View File

@@ -12,4 +12,9 @@ class OnlPlatform_x86_64_inventec_d7032q28b_r0(OnlPlatformInventec,
self.insmod('inv_platform')
self.insmod('inv_psoc')
self.insmod('inv_cpld')
self.new_i2c_device('inv_eeprom', 0x53, 0)
self.insmod('inv_eeprom')
self.insmod('swps')
self.insmod('vpd')
self.insmod('inv_pthread')
return True

View File

@@ -0,0 +1,2 @@
*x86*64*inventec*d7054q28b*.mk
onlpdump.mk

View File

@@ -1,5 +1,5 @@
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
KMODULES := $(wildcard *.c)
KMODULES := src
VENDOR := inventec
BASENAME := x86-64-inventec-d7054q28b
ARCH := x86_64

View File

@@ -0,0 +1,9 @@
#obj-m += gpio-ich.o
obj-m += inv_platform.o
obj-m += inv_cpld.o
obj-m += inv_psoc.o
obj-m += swps.o
swps-objs := inv_swps.o io_expander.o transceiver.o inv_mux.o
obj-m += vpd.o
vpd-objs := inv_vpd.o onie_tlvinfo.o
obj-m += inv_pthread.o

View File

@@ -15,8 +15,6 @@
#include <linux/err.h>
#include <linux/mutex.h>
//#include "I2CHostCommunication.h"
#define USE_SMBUS 1
/* definition */
@@ -162,7 +160,6 @@ static ssize_t set_ctl(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
//struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;
@@ -329,8 +326,6 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
struct cpld_data *data;
int status;
printk("+%s\n", __func__);
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -EIO;

View File

@@ -0,0 +1,281 @@
#include <linux/module.h>
#include <asm/io.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include "io_expander.h"
#include "inv_mux.h"
static struct mux_obj_s *mux_head_p = NULL;
/* ========== MUX object functions ==========
*/
int
_common_force_pull_gpio(int mem_addr,
int input,
int bit_offset){
unsigned int val = 0;
unsigned int targ = 0;
/* Get current value */
val = inl(mem_addr);
if (val == 0) {
SWPS_ERR("%s: inl:%d fail!\n", __func__, val);
return -1;
}
/* Count target value */
switch (input) {
case 0: /* Pull Low */
targ = (val & (~(1 << bit_offset)));
break;
case 1: /* Pull high */
targ = (val | (1 << bit_offset));
break;
default:
SWPS_ERR("%s: input state:%d incorrect!\n",
__func__, input);
return -1;
}
/* Setup gpio */
outl(targ, mem_addr);
if (targ != inl(mem_addr)){
SWPS_ERR("%s: outl:%d fail!\n", __func__, targ);
return -1;
}
SWPS_DEBUG("%s: done.\n", __func__);
return 0;
}
int
rangeley_force_pull_high(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
rangeley_force_pull_low(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
hedera_force_pull_high(struct mux_obj_s *self){
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5);
}
int
hedera_force_pull_low(struct mux_obj_s *self){
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5);
}
int
normal_gpio_pull_high(struct mux_obj_s *self){
return gpio_direction_output(self->gpio_num, 1);
}
int
normal_gpio_pull_low(struct mux_obj_s *self){
return gpio_direction_output(self->gpio_num, 0);
}
int
pca9548_reset_mux_all(struct mux_obj_s *self){
/* [Note] Power-on reset (PCA9548A-NXP)
* When power is applied to VDD, an internal Power-On Reset (POR)
* holds the PCA9548A in a reset condition until VDD has reached
* VPOR. At this point, the reset condition is released and the
* PCA9548A register and I2C-bus state machine are initialized to
* their default states (all zeroes) causing all the channels to
* be deselected. Thereafter, VDD must be lowered below 0.2 V for
* at least 5 us in order to reset the device.
*/
if (self->_pull_low(self) < 0) {
SWPS_ERR("%s: _pull_low fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS);
if (self->_pull_high(self) < 0) {
SWPS_ERR("%s: _pull_high fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS);
return 0;
}
int
common_reset_mux_all(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
init_gpio_4_force(struct mux_obj_s *self){
return 0;
}
int
init_gpio_4_normal(struct mux_obj_s *self){
int err = 0;
if (!gpio_is_valid(self->gpio_num)) {
SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num);
return -1;
}
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
if (err < 0) {
SWPS_ERR("%s: gpio_request fail <err>:%d <gpio>:%d\n",
__func__, err, self->gpio_num);
return -1;
}
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
return 0;
}
static int
_setup_muxctl_cb(struct mux_obj_s *self,
unsigned gpio){
char *mod_dsc = "ERR";
switch (gpio) {
case MUX_RST_GPIO_FORCE_RANGELEY:
self->gpio_num = gpio;
self->_pull_low = rangeley_force_pull_low;
self->_pull_high = rangeley_force_pull_high;
self->_init = init_gpio_4_force;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Rangeley force mode";
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_FORCE_HEDERA:
self->gpio_num = gpio;
self->_pull_low = hedera_force_pull_low;
self->_pull_high = hedera_force_pull_high;
self->_init = init_gpio_4_force;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Hedera force mode";
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_48_PAC9548:
self->gpio_num = gpio;
self->_pull_low = normal_gpio_pull_low;
self->_pull_high = normal_gpio_pull_high;
self->_init = init_gpio_4_normal;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Normal mode <gpio>:48";
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_69_PAC9548:
self->gpio_num = gpio;
self->_pull_low = normal_gpio_pull_low;
self->_pull_high = normal_gpio_pull_high;
self->_init = init_gpio_4_normal;
self->reset = pca9548_reset_mux_all;
mod_dsc = "Normal mode <gpio>:69";
goto ok_setup_muxctl_cb;
default:
break;
}
SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio);
return -1;
ok_setup_muxctl_cb:
SWPS_INFO("muxctl: %s.\n", mod_dsc);
return 0;
}
/* ========== MUX public functions ==========
*/
void
clean_mux_gpio(void){
if (!mux_head_p) {
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
return;
}
if (gpio_is_valid(mux_head_p->gpio_num)) {
gpio_free(mux_head_p->gpio_num);
}
kfree(mux_head_p);
mux_head_p = NULL;
SWPS_DEBUG("%s: done.\n", __func__);
}
EXPORT_SYMBOL(clean_mux_gpio);
int
reset_mux_gpio(void){
if (!mux_head_p) {
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
return -1;
}
if (mux_head_p->reset(mux_head_p) < 0){
SWPS_ERR("%s: reset fail!\n", __func__);
return -1;
}
return 0;
}
EXPORT_SYMBOL(reset_mux_gpio);
int
init_mux_gpio(unsigned gpio){
/* Create MUX control object */
if (mux_head_p) {
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
clean_mux_gpio();
}
/* Currently, it is using single muxctl architecture.
* In the future, it may use the multi-muxctl if HW add new features.
* (Ex: Port power-status control)
*/
mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
if (!mux_head_p) {
SWPS_ERR("%s: kzalloc fail!\n", __func__);
return -1;
}
/* Initial MUX controller */
if (_setup_muxctl_cb(mux_head_p, gpio) < 0){
SWPS_ERR("%s: _setup_muxctl_cb fail!\n", __func__);
return -1;
}
if (mux_head_p->_init(mux_head_p) < 0) {
SWPS_ERR("%s: init() fail\n", __func__);
goto err_init_mux_gpio;
}
/* Setup default value */
if (mux_head_p->_pull_high(mux_head_p) < 0) {
SWPS_ERR("%s: setup default fail!\n", __func__);
goto err_init_mux_gpio;
}
return 0;
err_init_mux_gpio:
clean_mux_gpio();
return -1;
}
EXPORT_SYMBOL(init_mux_gpio);
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,36 @@
#ifndef INV_MUX_H
#define INV_MUX_H
/* MUX basic information */
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
/* MUX reset GPIO define */
#define MUX_RST_GPIO_FORCE (30100)
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
#define MUX_RST_GPIO_48_PAC9548 (48)
#define MUX_RST_GPIO_69_PAC9548 (69)
/* MUX relate value define */
#define MUX_RST_WAIT_MS (1)
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
struct mux_obj_s {
unsigned gpio_num;
int (*_pull_high)(struct mux_obj_s *self);
int (*_pull_low)(struct mux_obj_s *self);
int (*_init)(struct mux_obj_s *self);
int (*reset)(struct mux_obj_s *self);
};
void clean_mux_gpio(void);
int reset_mux_gpio(void);
int init_mux_gpio(unsigned gpio);
#endif /* INV_MUX_H */

View File

@@ -1,5 +1,4 @@
#include <linux/i2c.h>
//#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -7,12 +6,6 @@
#include <linux/platform_device.h>
#include <linux/i2c/pca954x.h>
//#include <linux/i2c/pca953x.h>
//#include <linux/i2c/at24.h>
//#include <asm/gpio.h>
//#define IO_EXPAND_BASE 64
//#define IO_EXPAND_NGPIO 16
struct inv_i2c_board_info {
int ch;
@@ -76,9 +69,6 @@ static struct pca954x_platform_mode mux_modes_0_6[] = {
{.adap_id = bus_id(64),}, {.adap_id = bus_id(65),},
};
//no i2c device driver attach to mux 7
static struct pca954x_platform_data mux_data_0 = {
.modes = mux_modes_0,
.num_modes = 8,
@@ -154,24 +144,6 @@ static struct inv_i2c_board_info i2cdev_list[] = {
};
/////////////////////////////////////////////////////////////////////////////////////////
#if 0
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
.scl_pin = 58,
.sda_pin = 75,
.udelay = 5, //5:100kHz
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.scl_is_output_only = 0
};
static struct platform_device device_i2c_gpio0 = {
.name = "i2c-gpio",
.id = 0, // adapter number
.dev.platform_data = &i2c_gpio_platdata0,
};
#endif
static int __init inv_platform_init(void)
{
struct i2c_adapter *adap = NULL;
@@ -181,18 +153,6 @@ static int __init inv_platform_init(void)
printk("%s \n", __func__);
#if 0
//use i2c-gpio
//register i2c gpio
//config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3
outl( inl(0x533) | (1<<2), 0x533);
outl( inl(0x541) | (1<<3), 0x541);
ret = platform_device_register(&device_i2c_gpio0);
if (ret) {
printk(KERN_ERR "i2c-gpio: device_i2c_gpio0 register fail %d\n", ret);
}
#endif
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
adap = i2c_get_adapter( i2cdev_list[i].ch );
@@ -212,7 +172,6 @@ static int __init inv_platform_init(void)
}
module_init(inv_platform_init);
//arch_initcall(inv_platform_init);
MODULE_AUTHOR("Inventec");
MODULE_DESCRIPTION("Cypess Platform devices");

View File

@@ -16,11 +16,9 @@
#include <linux/mutex.h>
#include <linux/delay.h>
//#include "I2CHostCommunication.h"
#define IMPLEMENT_IPMI_CODE 1
int USE_IPMI=0;
//=================================
#if IMPLEMENT_IPMI_CODE
#include <linux/mutex.h>
#include <linux/completion.h>
@@ -54,7 +52,6 @@ static struct ipmi_recv_msg halt_recv_msg = {
.done = dummy_recv_free
};
#endif
//=================================
#define USE_SMBUS 1
@@ -122,7 +119,6 @@ struct __attribute__ ((__packed__)) psoc_layout {
struct psoc_psu_layout psu_info; //offset: 5a
};
/* definition */
/* definition */
#define PSOC_OFF(m) offsetof(struct psoc_layout, m)
#define PSOC_PSU_OFF(m) offsetof(struct psoc_psu_layout, m)
@@ -159,7 +155,7 @@ static void msg_handler(struct ipmi_recv_msg *recv_msg,void* handler_data)
int ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result, int* result_length)
{
int rv=0,i;
int rv=0;
struct ipmi_system_interface_addr addr;
uint8_t _data[data_length];
struct kernel_ipmi_msg msg;
@@ -167,10 +163,6 @@ int ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result,
if(!mutex_trylock(&ipmi_mutex)) return 0;
// for (i=0,rv=1; i<IPMI_MAX_INTF && rv; i++) {
// rv = ipmi_create_user(i, &ipmi_hndlrs, NULL, &ipmi_mh_user);
// }
if (rv < 0) {
mutex_unlock(&ipmi_mutex);
return rv;
@@ -190,7 +182,6 @@ int ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result,
rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0,&msg, &comp, &halt_smi_msg, &halt_recv_msg, 0);
if (rv) {
// ipmi_destroy_user(ipmi_mh_user);
mutex_unlock(&ipmi_mutex);
return -6;
}
@@ -203,7 +194,6 @@ int ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result,
memcpy(result,&halt_recv_msg.msg.data[1],halt_recv_msg.msg.data_len-1);
}
ipmi_free_recv_msg(&halt_recv_msg);
// ipmi_destroy_user(ipmi_mh_user);
mutex_unlock(&ipmi_mutex);
return rv;
}
@@ -312,19 +302,6 @@ else
#endif
}
#if 0
static u32 psoc_read32(struct i2c_client *client, u8 offset)
{
u32 value = 0;
u8 buf[4];
if( psoc_i2c_read(client, buf, offset, 4) == 4)
value = (buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3]);
return value;
}
#endif
static u16 psoc_read16(struct i2c_client *client, u8 offset)
{
u16 value = 0;

View File

@@ -0,0 +1,752 @@
/*************************************************************************
*
* inv_swps.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef INV_SWPS_H
#define INV_SWPS_H
#include "transceiver.h"
#include "io_expander.h"
#include "inv_mux.h"
/* Module settings */
#define SWP_CLS_NAME "swps"
#define SWP_DEV_PORT "port"
#define SWP_DEV_MODCTL "module"
#define SWP_RESET_PWD "inventec"
#define SWP_POLLING_PERIOD (300) /* msec */
#define SWP_POLLING_ENABLE (1)
#define SWP_AUTOCONFIG_ENABLE (1)
/* Module information */
#define SWP_AUTHOR "Neil <liao.neil@inventec.com>"
#define SWP_DESC "Inventec port and transceiver driver"
#define SWP_VERSION "4.2.3"
#define SWP_LICENSE "GPL"
#define SWPS_KERN_VER_AF_3_10 (1)
/* Module status define */
#define SWP_STATE_NORMAL (0)
#define SWP_STATE_I2C_DIE (-91)
/* [Note]:
* Functions and mechanism for auto-detect platform type is ready,
* But HW and BIOS not ready! We need to wait them.
* So, please do not use PLATFORM_TYPE_AUTO until they are ready.
* (2016.06.13)
*/
#define PLATFORM_TYPE_AUTO (100)
#define PLATFORM_TYPE_MAGNOLIA (111)
#define PLATFORM_TYPE_MAGNOLIA_FNC (112)
#define PLATFORM_TYPE_REDWOOD (121)
#define PLATFORM_TYPE_REDWOOD_FSL (122)
#define PLATFORM_TYPE_HUDSON32I_GA (131)
#define PLATFORM_TYPE_SPRUCE (141)
#define PLATFORM_TYPE_CYPRESS_GA1 (151) /* Up -> Down */
#define PLATFORM_TYPE_CYPRESS_GA2 (152) /* Down -> Up */
#define PLATFORM_TYPE_CYPRESS_BAI (153) /* Down -> Up */
/* Current running platfrom */
#define PLATFORM_SETTINGS PLATFORM_TYPE_CYPRESS_GA2
/* Define platform flag and kernel version */
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA)
#define SWPS_MAGNOLIA (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA_FNC)
#define SWPS_MAGNOLIA (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD)
#define SWPS_REDWOOD (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_REDWOOD_FSL)
#define SWPS_REDWOOD_FSL (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_HUDSON32I_GA)
#define SWPS_HUDSON32I_GA (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_SPRUCE)
#define SWPS_SPRUCE (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA1)
#define SWPS_CYPRESS_GA1 (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_GA2)
#define SWPS_CYPRESS_GA2 (1)
#define SWPS_KERN_VER_BF_3_8 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_CYPRESS_BAI)
#define SWPS_CYPRESS_BAI (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#endif
struct inv_platform_s {
int id;
char name[64];
};
struct inv_ioexp_layout_s {
int ioexp_id;
int ioexp_type;
struct ioexp_addr_s addr[4];
};
struct inv_port_layout_s {
int port_id;
int chan_id;
int ioexp_id;
int ioexp_offset;
int transvr_type;
int chipset_type;
int lane_id[8];
};
/* ==========================================
* Inventec Platform Settings
* ==========================================
*/
struct inv_platform_s platform_map[] = {
{PLATFORM_TYPE_AUTO, "Auto-Detect" },
{PLATFORM_TYPE_MAGNOLIA, "Magnolia" },
{PLATFORM_TYPE_MAGNOLIA_FNC, "Magnolia_FNC" },
{PLATFORM_TYPE_REDWOOD, "Redwood" },
{PLATFORM_TYPE_REDWOOD_FSL, "Redwood_FSL" },
{PLATFORM_TYPE_HUDSON32I_GA, "Hudson32i" },
{PLATFORM_TYPE_SPRUCE, "Spruce" },
{PLATFORM_TYPE_CYPRESS_GA1, "Cypress_GA1" },
{PLATFORM_TYPE_CYPRESS_GA2, "Cypress_GA2" },
{PLATFORM_TYPE_CYPRESS_BAI, "Cypress_BAI" },
};
/* ==========================================
* Magnolia Layout configuration
* ==========================================
*/
#ifdef SWPS_MAGNOLIA
unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s magnolia_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_MAGINOLIA_NAB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{1, IOEXP_TYPE_MAGINOLIA_NAB, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{2, IOEXP_TYPE_MAGINOLIA_NAB, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{3, IOEXP_TYPE_MAGINOLIA_NAB, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{4, IOEXP_TYPE_MAGINOLIA_NAB, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{5, IOEXP_TYPE_MAGINOLIA_NAB, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, }, /* addr[1] = I/O Expander N B */
},
{6, IOEXP_TYPE_MAGINOLIA_7AB, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[1] = I/O Expander 7 B */
},
};
struct inv_port_layout_s magnolia_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 16} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 15} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 14} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 13} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 24} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 23} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 22} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 21} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 28} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 27} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 26} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 25} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 32} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 31} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 30} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 29} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 48} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 47} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 46} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 45} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 52} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 51} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 50} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 49} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 56} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 55} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 54} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 53} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 60} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 59} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 58} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 57} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 64} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 63} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 62} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 61} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 68} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 67} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 66} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 65} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 72} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 71} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 70} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 69} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 76} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 75} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 74} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_2, { 73} },
{48, 58, 6, 0, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} },
{50, 60, 6, 2, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} },
{52, 62, 6, 4, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} },
};
#endif
/* ==========================================
* Redwood Layout configuration
* ==========================================
*/
#ifdef SWPS_REDWOOD
unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s redwood_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
};
struct inv_port_layout_s redwood_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} },
{ 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} },
{ 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} },
{ 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} },
{ 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} },
{ 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} },
{ 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} },
{ 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} },
{ 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} },
{ 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} },
{10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} },
{11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} },
{12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} },
{13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} },
{14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} },
{15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} },
{16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} },
{17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} },
{18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} },
{19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} },
{20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} },
{21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} },
{23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} },
{24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
{28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113,114,115,116} },
{29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121,122,123,124} },
{31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125,126,127,128} },
};
#endif
/* ==========================================
* Hudson32i Layout configuration
* ==========================================
*/
#ifdef SWPS_HUDSON32I_GA
unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_HUDSON32IGA_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */
},
{1, IOEXP_TYPE_HUDSON32IGA_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x24 */
},
{2, IOEXP_TYPE_HUDSON32IGA_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */
},
{3, IOEXP_TYPE_HUDSON32IGA_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0x25 */
},
};
struct inv_port_layout_s hudson32iga_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 1, 2, 3, 4} },
{ 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 5, 6, 7, 8} },
{ 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 9, 10, 11, 12} },
{ 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 13, 14, 15, 16} },
{ 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 17, 18, 19, 20} },
{ 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 21, 22, 23, 24} },
{ 6, 12, 0, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 25, 26, 27, 28} },
{ 7, 13, 0, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 29, 30, 31, 32} },
{ 8, 14, 1, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 33, 34, 35, 36} },
{ 9, 15, 1, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 37, 38, 39, 40} },
{10, 16, 1, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 41, 42, 43, 44} },
{11, 17, 1, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 45, 46, 47, 48} },
{12, 18, 1, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 49, 50, 51, 52} },
{13, 19, 1, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 53, 54, 55, 56} },
{14, 20, 1, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 57, 58, 59, 60} },
{15, 21, 1, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 61, 62, 63, 64} },
{16, 22, 2, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 65, 66, 67, 68} },
{17, 23, 2, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 69, 70, 71, 72} },
{18, 24, 2, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 73, 74, 75, 76} },
{19, 25, 2, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} },
{20, 26, 2, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} },
{21, 27, 2, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 85, 86, 87, 88} },
{22, 28, 2, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 89, 90, 91, 92} },
{23, 29, 2, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 93, 94, 95, 96} },
{24, 30, 3, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} },
{25, 31, 3, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} },
{26, 32, 3, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} },
{27, 33, 3, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} },
{28, 34, 3, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {113,114,115,116} },
{29, 35, 3, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {117,118,119,120} },
{30, 36, 3, 6, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {121,122,123,124} },
{31, 37, 3, 7, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {125,126,127,128} },
};
#endif
/* ==========================================
* Spruce Layout configuration
* ==========================================
*/
#ifdef SWPS_SPRUCE
unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s spruce_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_SPRUCE_7AB, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 7A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xf0, 0x33}, }, }, /* addr[2] = I/O Expander 7B */
},
};
struct inv_port_layout_s spruce_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 6, 0, 0, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 81, 82, 83, 84} },
{ 1, 7, 0, 1, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 77, 78, 79, 80} },
{ 2, 8, 0, 2, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, { 97, 98, 99,100} },
{ 3, 9, 0, 3, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {101,102,103,104} },
{ 4, 10, 0, 4, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {105,106,107,108} },
{ 5, 11, 0, 5, TRANSVR_TYPE_QSFP_PLUS, BCM_CHIP_TYPE_TRIDENT_2, {109,110,111,112} },
};
#endif
/* ==========================================
* Cypress Layout configuration (Inventec version [Up->Down])
* ==========================================
*/
#ifdef SWPS_CYPRESS_GA1
unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s cypress_ga1_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} },
{48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
};
#endif
/* ==========================================
* Cypress Layout configuration (Inventec version [Down->Up])
* ==========================================
*/
#ifdef SWPS_CYPRESS_GA2
unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s cypress_ga2_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} },
{ 1, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} },
{ 2, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} },
{ 3, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} },
{ 4, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} },
{ 5, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} },
{ 6, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} },
{ 7, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} },
{ 8, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} },
{ 9, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} },
{10, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} },
{11, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} },
{12, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} },
{13, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} },
{14, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} },
{15, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} },
{16, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} },
{17, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} },
{18, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} },
{19, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} },
{20, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} },
{21, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} },
{22, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} },
{23, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} },
{24, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} },
{25, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} },
{26, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} },
{27, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} },
{28, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} },
{29, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} },
{30, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} },
{31, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} },
{32, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} },
{33, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} },
{34, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} },
{35, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} },
{36, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} },
{37, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} },
{38, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} },
{39, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} },
{40, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} },
{41, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} },
{42, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} },
{43, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} },
{44, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} },
{45, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} },
{46, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} },
{47, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} },
{48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
};
#endif
/* ==========================================
* Cypress Layout configuration (BaiDu version)
* ==========================================
*/
#ifdef SWPS_CYPRESS_BAI
unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s cypress_b_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 2} },
{ 2, 10, 0, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 1} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 4} },
{ 4, 12, 0, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 3} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 6} },
{ 6, 14, 0, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 5} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 8} },
{ 8, 16, 0, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 7} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 10} },
{10, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 9} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 12} },
{12, 20, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 11} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 22} },
{14, 22, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 21} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 24} },
{16, 24, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 23} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 34} },
{18, 26, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 33} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 36} },
{20, 28, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 35} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 38} },
{22, 30, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 37} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 40} },
{24, 32, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 39} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 42} },
{26, 34, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 41} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 44} },
{28, 36, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 43} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 50} },
{30, 38, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 49} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 52} },
{32, 40, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 51} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 54} },
{34, 42, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 53} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 56} },
{36, 44, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 55} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 66} },
{38, 46, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 65} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 68} },
{40, 48, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 67} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 70} },
{42, 50, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 69} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 72} },
{44, 52, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 71} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 82} },
{46, 54, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 81} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 84} },
{48, 56, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TOMAHAWK, { 83} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{50, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{52, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{54, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
};
#endif
/* ==========================================
* Redwood_fsl Layout configuration
* ==========================================
*/
#ifdef SWPS_REDWOOD_FSL
unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_REDWOOD_P01P08, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{1, IOEXP_TYPE_REDWOOD_P09P16, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x25, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{2, IOEXP_TYPE_REDWOOD_P01P08, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
{3, IOEXP_TYPE_REDWOOD_P09P16, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[0] = I/O Expander 1-4 A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0x00}, {0x00, 0x0f}, }, /* addr[1] = I/O Expander 1-4 B */
{0, 0x24, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 5 B */
},
};
struct inv_port_layout_s redwood_fsl_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 22, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 1, 2, 3, 4} },
{ 1, 23, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 5, 6, 7, 8} },
{ 2, 24, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 9, 10, 11, 12} },
{ 3, 25, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 13, 14, 15, 16} },
{ 4, 26, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 17, 18, 19, 20} },
{ 5, 27, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 21, 22, 23, 24} },
{ 6, 28, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 25, 26, 27, 28} },
{ 7, 29, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 29, 30, 31, 32} },
{ 8, 30, 1, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 33, 34, 35, 36} },
{ 9, 31, 1, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 37, 38, 39, 40} },
{10, 32, 1, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 41, 42, 43, 44} },
{11, 33, 1, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 45, 46, 47, 48} },
{12, 34, 1, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 49, 50, 51, 52} },
{13, 35, 1, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 53, 54, 55, 56} },
{14, 36, 1, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 57, 58, 59, 60} },
{15, 37, 1, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 61, 62, 63, 64} },
{16, 6, 2, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 65, 66, 67, 68} },
{17, 7, 2, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 69, 70, 71, 72} },
{18, 8, 2, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 73, 74, 75, 76} },
{19, 9, 2, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 77, 78, 79, 80} },
{20, 10, 2, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 81, 82, 83, 84} },
{21, 11, 2, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 85, 86, 87, 88} },
{22, 12, 2, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 89, 90, 91, 92} },
{23, 13, 2, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 93, 94, 95, 96} },
{24, 14, 3, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, { 97, 98, 99,100} },
{25, 15, 3, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {101,102,103,104} },
{26, 16, 3, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {105,106,107,108} },
{27, 17, 3, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {109,110,111,112} },
{28, 18, 3, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {113,114,115,116} },
{29, 19, 3, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {117,118,119,120} },
{30, 20, 3, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {121,122,123,124} },
{31, 21, 3, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TOMAHAWK, {125,126,127,128} },
};
#endif
#endif /* INV_SWPS_H */

View File

@@ -0,0 +1,354 @@
/*************************************************************************
*
* inv_vpd.c
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/dmi.h>
#include <linux/i2c.h>
#include "inv_vpd.h"
#include "onie_tlvinfo.h"
static int vpd_major;
static struct class *vpd_class_p = NULL;
static char cEeprom[SYS_EEPROM_MAX_SIZE];
static DEFINE_MUTEX(vpd_mutex);
static int
__swp_match(struct device *dev,
#ifdef VPD_KERN_VER_AF_3_10
const void *data){
#else
void *data){
#endif
char *name = (char *)data;
if (strcmp(dev_name(dev), name) == 0)
return 1;
return 0;
}
static
int get_vpd_data(struct i2c_client *pi2c_client, int i_offset, char *c_buf)
{
int iRet;
read_eeprom( pi2c_client, cEeprom);
iRet = tlvinfo_decode_tlv(cEeprom, i_offset,c_buf);
return iRet;
}
static
int write_vpd_data(struct i2c_client *pi2c_client, int i_offset, char *c_buf)
{
int iErr = 0;
if (read_eeprom(pi2c_client, cEeprom)) {
printk(KERN_ERR "write vpd data eror at %d-%s\n", __LINE__, __FUNCTION__);
return -1;
}
if (tlvinfo_delete_tlv(cEeprom, i_offset) == TRUE) {
}
if (c_buf) {
if(!tlvinfo_add_tlv(cEeprom, i_offset , c_buf)) {
printk(KERN_ERR "write vpd data eror at %d-%s\n", __LINE__, __FUNCTION__);
iErr = -1;
} else {
iErr = prog_eeprom(pi2c_client,cEeprom);
}
}
return iErr;
}
static struct device *
get_swpdev_by_name(char *name){
struct device *dev = class_find_device(vpd_class_p,
NULL,
name,
__swp_match);
return dev;
}
static ssize_t
store_attr_vpd(struct device *dev_p,
struct device_attribute *attr_p,
const char *buf_p,
size_t count){
struct i2c_client *pi2c_client = dev_get_drvdata(dev_p);
struct vpd_device_attribute *attr = to_vpd_dev_attr(attr_p);
int iOffset = attr->index;
int iErr , iLen;
char *pChar;
if (!pi2c_client){
return -ENODEV;
}
mutex_lock(&vpd_mutex);
//-strip 0x0a in the last byte.
for (iLen = 0, pChar = buf_p;
iLen < 255 && *pChar != 0;
iLen++, pChar++) ;
if (iLen !=0 && *pChar == 0 && *(pChar-1) == 0x0a)
*(pChar - 1) = 0;
//-
iErr = write_vpd_data( pi2c_client, iOffset, buf_p);
mutex_unlock(&vpd_mutex);
return count;
}
static ssize_t
show_attr_vpd(struct device *dev_p,
struct device_attribute *attr_p,
char *buf_p){
struct i2c_client *pi2c_client = dev_get_drvdata(dev_p);
struct vpd_device_attribute *attr = to_vpd_dev_attr(attr_p);
int iOffset = attr->index;
int iErr , iLen;
if (!pi2c_client){
return -ENODEV;
}
mutex_lock(&vpd_mutex);
iErr = get_vpd_data( pi2c_client, iOffset, buf_p);
mutex_unlock(&vpd_mutex);
if( iErr <= 0 )
iLen = 0;
else
iLen = snprintf(buf_p, TLV_DECODE_VALUE_MAX_LEN, "%s\n", buf_p);
return iLen;
}
/* ================= Vpd attribute ========================
*/
static VPD_DEVICE_ATTR(product_name ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_PRODUCT_NAME );
static VPD_DEVICE_ATTR(pn ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_PART_NUMBER );
static VPD_DEVICE_ATTR(sn ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_SERIAL_NUMBER );
static VPD_DEVICE_ATTR(base_mac_addr,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MAC_BASE );
static VPD_DEVICE_ATTR(man_date ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MANUF_DATE );
static VPD_DEVICE_ATTR(dev_ver ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_DEVICE_VERSION );
static VPD_DEVICE_ATTR(label_rev ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_LABEL_REVISION );
static VPD_DEVICE_ATTR(plat_name ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_PLATFORM_NAME );
static VPD_DEVICE_ATTR(ldr_ver ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_ONIE_VERSION );
static VPD_DEVICE_ATTR(mac_addr ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MAC_SIZE );
static VPD_DEVICE_ATTR(manufacturer ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MANUF_NAME );
static VPD_DEVICE_ATTR(country_code ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_MANUF_COUNTRY );
static VPD_DEVICE_ATTR(vendor_name ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_VENDOR_NAME );
static VPD_DEVICE_ATTR(diag_ver ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_DIAG_VERSION );
static VPD_DEVICE_ATTR(service_tag ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_SERVICE_TAG );
static VPD_DEVICE_ATTR(vendor_ext ,S_IWUSR|S_IRUGO, show_attr_vpd, store_attr_vpd, TLV_CODE_VENDOR_EXT );
static VPD_DEVICE_ATTR(crc32 ,S_IRUGO, show_attr_vpd, NULL, TLV_CODE_CRC_32 );
static void
clean_vpd_common(void)
{
dev_t dev_num;
struct device *device_p;
device_p = get_swpdev_by_name(VPD_DEVICE);
if (device_p){
dev_num = MKDEV(vpd_major, 1);
device_unregister(device_p);
device_destroy(vpd_class_p, dev_num);
}
VPD_DEBUG("%s: done.\n", __func__);
}
static struct register_attr VpdRegAttr[VPD_ENTRY_SIZE ] ={
{ &vpd_dev_attr_product_name.dev_attr, "vpd_dev_attr_product_name"},
{ &vpd_dev_attr_pn.dev_attr, "vpd_dev_attr_pn"},
{ &vpd_dev_attr_sn.dev_attr, "vpd_dev_attr_sn"},
{ &vpd_dev_attr_base_mac_addr.dev_attr, "vpd_dev_attr_base_mac_addr"},
{ &vpd_dev_attr_man_date.dev_attr, "vpd_dev_attr_man_date"},
{ &vpd_dev_attr_dev_ver.dev_attr, "vpd_dev_attr_dev_ver"},
{ &vpd_dev_attr_label_rev.dev_attr, "vpd_dev_attr_label_rev"},
{ &vpd_dev_attr_plat_name.dev_attr, "vpd_dev_attr_plat_name"},
{ &vpd_dev_attr_ldr_ver.dev_attr, "vpd_dev_attr_ldr_ver"},
{ &vpd_dev_attr_mac_addr.dev_attr, "vpd_dev_attr_mac_addr"},
{ &vpd_dev_attr_manufacturer.dev_attr, "vpd_dev_attr_manufacturer"},
{ &vpd_dev_attr_country_code.dev_attr, "vpd_dev_attr_country_code"},
{ &vpd_dev_attr_vendor_name.dev_attr, "vpd_dev_attr_vendor_name"},
{ &vpd_dev_attr_diag_ver.dev_attr, "vpd_dev_attr_diag_ver"},
{ &vpd_dev_attr_service_tag.dev_attr, "vpd_dev_attr_service_tag"},
{ &vpd_dev_attr_vendor_ext.dev_attr, "vpd_dev_attr_vendor_ext"},
{ &vpd_dev_attr_crc32.dev_attr, "vpd_dev_attr_crc32"},
};
static int
register_vpd_attr(struct device *device_p){
char *err_attr = NULL;
int i;
for( i = 0 ; i <VPD_ENTRY_SIZE ;i++ ){
if(device_create_file(device_p, VpdRegAttr[ i ].attr) < 0) {
err_attr = VpdRegAttr[ i ].errmsg;
goto err_register_vpd_attr;
}
}
return 0;
err_register_vpd_attr:
VPD_ERR("%s: %s\n", __func__, err_attr);
return -1;
}
static int
register_vpd_device(void)
{
struct device *device_p = NULL;
int minor_comm = 0; /* Default minor number for common device */
dev_t dev_num = MKDEV(vpd_major, minor_comm);
char *err_msg = "ERROR";
struct i2c_adapter *adap;
struct i2c_client *vpd_i2c_client = NULL;
vpd_i2c_client = kzalloc(sizeof(*vpd_i2c_client), GFP_KERNEL);
if (!vpd_i2c_client){
printk(KERN_ERR "can not kzalloc client:%d", VPD_I2C_BUS);
goto err_register_vpd_device;
}
adap = i2c_get_adapter(VPD_I2C_BUS);
vpd_i2c_client->adapter = adap;
vpd_i2c_client->addr = VPD_I2C_ADDR;
device_p = device_create(vpd_class_p, /* struct class *cls */
NULL, /* struct device *parent */
dev_num, /* dev_t devt */
vpd_i2c_client, /* void *private_data */
VPD_DEVICE); /* const char *fmt */
if (IS_ERR(device_p)){
err_msg = "device_create fail";
goto err_register_vpd_device_1;
}
if (register_vpd_attr(device_p) < 0) {
err_msg = "register_vpd_attr fail";
goto err_register_vpd_device_2;
}
return 0;
err_register_vpd_device_2:
device_unregister(device_p);
device_destroy(vpd_class_p, dev_num);
err_register_vpd_device_1:
kfree(vpd_i2c_client);
vpd_i2c_client = NULL;
err_register_vpd_device:
VPD_ERR("%s: %s\n", __func__, err_msg);
return -1;
}
static int
register_vpd_module(void)
{
dev_t vpd_devt = 0;
if (alloc_chrdev_region(&vpd_devt, 0, 1, VPD_DEVICE) < 0){
VPD_WARN("Allocate VPD MAJOR failure! \n");
goto err_register_vpd_module;
}
vpd_major = MAJOR(vpd_devt);
/* Create class object */
vpd_class_p = class_create(THIS_MODULE, EEPROM_CLASS);
if (IS_ERR(vpd_class_p)) {
VPD_ERR("Create class failure! \n");
goto err_register_vpd_module_1;
}
return 0;
err_register_vpd_module_1:
unregister_chrdev_region(MKDEV(vpd_major, 0), 1);
err_register_vpd_module:
return -1;
}
static int
init_vpd_common(void)
{
char *err_msg = "ERR";
if (register_vpd_device() < 0) {
err_msg = "register_vpd_device fail";
goto err_init_vpd_common;
}
return 0;
err_init_vpd_common:
VPD_ERR("%s: %s\n", __func__, err_msg);
return -1;
}
static int __init
vpd_module_init(void)
{
if (register_vpd_module() < 0){
goto err_vpd_module_init;
}
if (init_vpd_common() < 0){
goto err_vpd_module_init_1;
}
VPD_INFO("Inventec vpd module V.%s initial success.\n", VPD_VERSION);
return 0;
err_vpd_module_init_1:
class_unregister(vpd_class_p);
class_destroy(vpd_class_p);
unregister_chrdev_region(MKDEV(vpd_major, 0), 1);
err_vpd_module_init:
VPD_ERR("Inventec vpd module V.%s initial failure.\n", VPD_VERSION);
return -1;
}
static void __exit
vpd_module_exit(void)
{
clean_vpd_common();
class_unregister(vpd_class_p);
class_destroy(vpd_class_p);
unregister_chrdev_region(MKDEV(vpd_major, 0), 1);
VPD_INFO("Remove Inventec vpd module success.\n");
}
/* Module information */
MODULE_AUTHOR(VPD_AUTHOR);
MODULE_DESCRIPTION(VPD_DESC);
MODULE_VERSION(VPD_VERSION);
MODULE_LICENSE(VPD_LICENSE);
module_init(vpd_module_init);
module_exit(vpd_module_exit);

View File

@@ -0,0 +1,64 @@
/*************************************************************************
*
* inv_vpd.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef INV_VPD_H
#define INV_VPD_H
#define EEPROM_CLASS "eeprom"
#define VPD_DEVICE "vpd"
#define VPD_AUTHOR "Neil <liao.neil@inventec.com>"
#define VPD_DESC "Inventec eeprom vpd driver"
#define VPD_VERSION "1.0.0"
#define VPD_LICENSE "GPL"
#define VPD_ENTRY_SIZE (17)
#define VPD_I2C_BUS (0)
#define VPD_I2C_ADDR (0x53)
#define VPD_KERN_VER_AF_3_10 (1)
struct register_attr {
struct device_attribute *attr;
char * errmsg;
};
struct vpd_device_attribute{
struct device_attribute dev_attr;
int index;
};
#define to_vpd_dev_attr(_dev_attr) \
container_of(_dev_attr, struct vpd_device_attribute, dev_attr)
#define VPD_ATTR(_name, _mode, _show, _store, _index) \
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
.index = _index }
#define VPD_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
struct vpd_device_attribute vpd_dev_attr_##_name \
= VPD_ATTR(_name, _mode, _show, _store, _index)
#define VPD_INFO(fmt, args...) printk( KERN_INFO "[VPD] " fmt, ##args)
#define VPD_WARN(fmt, args...) printk( KERN_WARNING "[VPD] " fmt, ##args)
#define VPD_ERR(fmt, args...) printk( KERN_ERR "[VPD] " fmt, ##args)
#ifdef DEBUG_VPD
# define VPD_DEBUG(fmt, args...) printk( KERN_DEBUG "[VPD] " fmt, ##args)
#else
# define VPD_DEBUG(fmt, args...)
#endif
#endif /* INV_VPD_H */

View File

@@ -0,0 +1,185 @@
/*************************************************************************
*
* io_expander.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef IO_EXPANDER_H
#define IO_EXPANDER_H
#include <linux/types.h>
/* IOEXP type define (SFP series) */
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
#define IOEXP_TYPE_CYPRESS_NABC (10102)
/* IOEXP type define (QSFP series) */
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
#define IOEXP_TYPE_SPRUCE_7AB (10206)
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
/* IOEXP mode define */
#define IOEXP_MODE_POLLING (19000)
#define IOEXP_MODE_DIRECT (19001)
/* IOEXP state define */
#define STATE_IOEXP_NORMAL (0)
#define STATE_IOEXP_INIT (-1)
#define STATE_IOEXP_ABNORMAL (-2)
/* IOEXP error code define */
#define ERR_IOEXP_NOTSUPPORT (-100)
#define ERR_IOEXP_UNINIT (-101)
#define ERR_IOEXP_BADCONF (-102)
#define ERR_IOEXP_ABNORMAL (-103)
#define ERR_IOEXP_NOSTATE (-104)
#define ERR_IOEXP_BADINPUT (-105)
#define ERR_IOEXP_UNEXCPT (-199)
#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args)
#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args)
#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args)
#ifdef DEBUG_SWPS
# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args)
#else
# define SWPS_DEBUG(fmt, args...)
#endif
struct ioexp_addr_s {
int chan_id;
int chip_addr;
int read_offset[8];
int write_offset[8];
int conf_offset[8];
uint8_t data_default[8];
uint8_t conf_default[8];
};
struct ioexp_i2c_s {
int chip_id;
struct i2c_client *i2c_client_p;
struct ioexp_i2c_s *next;
};
struct ioexp_bitmap_s {
int chip_id; /* IOEXP chip id */
int ioexp_voffset; /* IOEXP virtual offset */
int bit_shift;
};
struct ioexp_map_s {
int chip_amount; /* Number of chips that IOEXP object content */
int data_width; /* Number of (Read/Write/Config) bytes */
struct ioexp_addr_s *map_addr; /* Chip address info */
struct ioexp_bitmap_s map_present[8]; /* IOEXP for SFP / QSFP */
struct ioexp_bitmap_s map_tx_disable[8]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_tx_fault[8]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_rxlos[8]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_reset[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_lpmod[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_modsel[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_hard_rs0[8]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_hard_rs1[8]; /* IOEXP for QSFP */
};
struct ioexp_data_s {
uint8_t data[8];
};
struct ioexp_obj_s {
/* ============================
* Object public property
* ============================
*/
int ioexp_id;
int ioexp_type;
/* ============================
* Object private property
* ============================
*/
struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */
struct ioexp_map_s *ioexp_map_p;
struct ioexp_obj_s *next;
struct ioexp_i2c_s *i2c_head_p;
struct mutex lock;
int mode;
int state;
/* ===========================================
* Object public functions
* ===========================================
*/
int (*get_present)(struct ioexp_obj_s *self, int virt_offset);
int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset);
int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset);
int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset);
int (*get_reset)(struct ioexp_obj_s *self, int virt_offset);
int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset);
int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset);
int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset);
int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset);
int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val);
/* ===========================================
* Object private functions
* ===========================================
*/
int (*init)(struct ioexp_obj_s *self);
int (*check)(struct ioexp_obj_s *self);
int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name);
int (*fsm_4_direct)(struct ioexp_obj_s* self);
int (*fsm_4_polling)(struct ioexp_obj_s* self);
};
struct ioexp_obj_s* get_ioexp_obj(int ioexp_id);
int create_ioexp_obj(int ioexp_id,
int ioexp_type,
struct ioexp_addr_s *addr_map_p,
int run_mode);
int init_ioexp_objs(void);
int check_ioexp_objs(void);
void clean_ioexp_objs(void);
void unlock_ioexp_all(void);
int lock_ioexp_all(void);
int check_channel_tier_1(void);
int resync_channel_tier_1(void);
/* Macro for bit control */
#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift)))
#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift)))
#endif /* IO_EXPANDER_H */

View File

@@ -0,0 +1,820 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ctype.h>
//#include <linux/crc32.h>
#include <linux/delay.h>
//#include <linux/slab.h>
//#include <linux/platform_device.h>
#include "onie_tlvinfo.h"
/* Set to 1 if we've read EEPROM into memory */
static int has_been_read = 0;
int read_sys_eeprom(struct i2c_client *pi2c_client,void *eeprom_data, int offset, int len);
int write_sys_eeprom(struct i2c_client *pi2c_client, void *eeprom_data, int len);
static inline int is_multicast_ether_addr(const u_int8_t *addr)
{
return 0x01 & addr[0];
}
static inline int is_zero_ether_addr(const u_int8_t *addr)
{
return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
}
static inline int is_valid_ether_addr(const u_int8_t *addr)
{
return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
}
#if 0
static unsigned int crc32(unsigned char const *p, unsigned int len)
{
int i;
unsigned int crc = 0;
while (len--) {
crc ^= *p++;
for (i = 0; i < 8; i++)
crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
}
return crc;
}
#else
static unsigned long crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
static unsigned long crc32(unsigned char const *buf, unsigned int size)
{
unsigned char *p = buf;
unsigned long crc = 0;
crc = crc ^ ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}
#endif
static int set_bytes(char *buf, const char *string, int * converted_accum)
{
char *p = (char *) string;
int i;
uint byte;
if (!p) {
printk("ERROR: NULL string passed in.\n");
return -1;
}
/* Convert string to bytes */
for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0);
i++) {
while ((*p == ' ') || (*p == '\t') || (*p == ',') ||
(*p == ';')) {
p++;
}
if (*p != 0) {
if (!isdigit(*p)) {
printk("ERROR: Non-digit found in byte string: (%s)\n", string);
return -1;
}
byte = strtoul(p, &p, 0);
if (byte >= 256) {
printk("ERROR: The value specified is greater than 255: (%u) " \
"in string: %s\n", byte, string);
return -1;
}
buf[i] = byte & 0xFF;
}
}
if ((i == TLV_VALUE_MAX_LEN) && (*p != 0)) {
printk("ERROR: Trying to assign too many bytes "
"(max: %d) in string: %s\n", TLV_VALUE_MAX_LEN, string);
return -1;
}
*converted_accum = i;
return 0;
}
/*
* set_date
*
* Validates the format of the data string
*
* This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss)
* and validates that the format is correct. If so the string is copied
* to the supplied buffer.
*/
static int set_date(char *buf, const char *string)
{
int i;
if (!string) {
printk("ERROR: NULL date string passed in.\n");
return -1;
}
if (strlen(string) != 19) {
printk("ERROR: Date strlen() != 19 -- %d\n", strlen(string));
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", string);
return -1;
}
for (i = 0; string[i] != 0; i++) {
switch (i) {
case 2:
case 5:
if (string[i] != '/') {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
case 10:
if (string[i] != ' ') {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
case 13:
case 16:
if (string[i] != ':') {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
default:
if (!isdigit(string[i])) {
printk("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
string);
return -1;
}
break;
}
}
strcpy(buf, string);
return 0;
}
/*
* is_valid_tlv
*
* Perform basic sanity checks on a TLV field. The TLV is pointed to
* by the parameter provided.
* 1. The type code is not reserved (0x00 or 0xFF)
*/
static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv)
{
return((tlv->type != 0x00) && (tlv->type != 0xFF));
}
/*
* set_mac
*
* Converts a string MAC address into a binary buffer.
*
* This function takes a pointer to a MAC address string
* (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number).
* The string format is verified and then converted to binary and
* stored in a buffer.
*/
static int set_mac(char *buf, const char *string)
{
char *p = (char *) string;
int i;
int err = 0;
char *end;
if (!p) {
printk("ERROR: NULL mac addr string passed in.\n");
return -1;
}
if (strlen(p) != 17) {
printk("ERROR: MAC address strlen() != 17 -- %d\n", strlen(p));
printk("ERROR: Bad MAC address format: %s\n", string);
return -1;
}
for (i = 0; i < 17; i++) {
if ((i % 3) == 2) {
if (p[i] != ':') {
err++;
printk("ERROR: mac: p[%i] != :, found: `%c'\n",
i, p[i]);
break;
}
continue;
} else if (!isxdigit(p[i])) {
err++;
printk("ERROR: mac: p[%i] != hex digit, found: `%c'\n",
i, p[i]);
break;
}
}
if (err != 0) {
printk("ERROR: Bad MAC address format: %s\n", string);
return -1;
}
/* Convert string to binary */
for (i = 0, p = (char *)string; i < 6; i++) {
buf[i] = p ? strtoul(p, &end, 16) : 0;
if (p) {
p = (*end) ? end + 1 : end;
}
}
if (!is_valid_ether_addr((char *)buf)) {
printk("ERROR: MAC address must not be 00:00:00:00:00:00, "
"a multicast address or FF:FF:FF:FF:FF:FF.\n");
printk("ERROR: Bad MAC address format: %s\n", string);
return -1;
}
return 0;
}
/*
* is_valid_tlvinfo_header
*
* Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM
* data pointed to by the parameter:
* 1. First 8 bytes contain null-terminated ASCII string "TlvInfo"
* 2. Version byte is 1
* 3. Total length bytes contain value which is less than or equal
* to the allowed maximum (2048-11)
*
*/
static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr)
{
int max_size = TLV_TOTAL_LEN_MAX;
return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) &&
(hdr->version == TLV_INFO_VERSION) &&
(be16_to_cpu(hdr->totallen) <= max_size) );
}
/*
* decode_tlv_value
*
* Decode a single TLV value into a string.
* The validity of EEPROM contents and the TLV field have been verified
* prior to calling this function.
*/
#define DECODE_NAME_MAX 20
static void decode_tlv_value(tlvinfo_tlv_t * tlv, char* value)
{
int i;
switch (tlv->type) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_MANUF_DATE:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
memcpy(value, tlv->value, tlv->length);
value[tlv->length] = 0;
break;
case TLV_CODE_MAC_BASE:
snprintf(value, MAX_STRING_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3], tlv->value[4], tlv->value[5]);
break;
case TLV_CODE_DEVICE_VERSION:
snprintf(value, MAX_STRING_SIZE, "%u", tlv->value[0]);
break;
case TLV_CODE_MAC_SIZE:
snprintf(value, MAX_STRING_SIZE, "%u", (tlv->value[0] << 8) | tlv->value[1]);
break;
case TLV_CODE_VENDOR_EXT:
value[0] = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length);
i++) {
snprintf(value, MAX_STRING_SIZE, "%s 0x%02X", value, tlv->value[i]);
}
break;
case TLV_CODE_CRC_32:
snprintf(value, MAX_STRING_SIZE, "0x%02X%02X%02X%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3]);
break;
default:
value[0] = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length);
i++) {
snprintf(value, MAX_STRING_SIZE, "%s 0x%02X", value, tlv->value[i]);
}
break;
}
}
/*
* is_checksum_valid
*
* Validate the checksum in the provided TlvInfo EEPROM data. First,
* verify that the TlvInfo header is valid, then make sure the last
* TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
* and compare it to the value stored in the EEPROM CRC-32 TLV.
*/
static bool is_checksum_valid(u_int8_t *eeprom)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_crc;
unsigned int calc_crc;
unsigned int stored_crc;
// Is the eeprom header valid?
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return(FALSE);
}
// Is the last TLV a CRC?
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) -
(sizeof(tlvinfo_tlv_t) + 4)];
if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) {
return(FALSE);
}
// Calculate the checksum
calc_crc = crc32((void *)eeprom, sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) |
(eeprom_crc->value[2] << 8) | eeprom_crc->value[3]);
//printk(KERN_ERR "[SWPS] cal_crc =0x%x, stored_crc =0x%x\n", calc_crc, stored_crc);
//return(calc_crc == stored_crc);
return 1;
}
/*
* update_crc
*
* This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then
* one is added. This function should be called after each update to the
* EEPROM structure, to make sure the CRC is always correct.
*/
static void update_crc(u_int8_t *eeprom)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_crc;
unsigned int calc_crc;
// Is the eeprom header valid?
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return;
}
// Is the last TLV a CRC?
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) -
(sizeof(tlvinfo_tlv_t) + 4)];
if (eeprom_crc->type != TLV_CODE_CRC_32) {
if ((be16_to_cpu(eeprom_hdr->totallen) + sizeof(tlvinfo_tlv_t) + 4) >
TLV_TOTAL_LEN_MAX) {
return;
}
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(
eeprom_hdr->totallen)];
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) +
sizeof(tlvinfo_tlv_t) + 4);
eeprom_crc->type = TLV_CODE_CRC_32;
}
eeprom_crc->length = 4;
// Calculate the checksum
calc_crc = crc32((void *)eeprom,
sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF;
eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF;
eeprom_crc->value[2] = (calc_crc >> 8) & 0xFF;
eeprom_crc->value[3] = (calc_crc >> 0) & 0xFF;
}
/*
* show_eeprom
*
* Display the contents of the EEPROM
*/
/*
* read_eeprom
*
* Read the EEPROM into memory, if it hasn't already been read.
*/
int read_eeprom( struct i2c_client *pi2c_client, u_int8_t *eeprom)
{
int ret;
tlvinfo_header_t *eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t *eeprom_tlv = (tlvinfo_tlv_t *)&eeprom[
sizeof(tlvinfo_header_t)];
if (has_been_read)
return 0;
/* Read the header */
ret = read_sys_eeprom( pi2c_client,(void *)eeprom_hdr, 0, sizeof(tlvinfo_header_t));
/* If the header was successfully read, read the TLVs */
if ((ret == 0) && is_valid_tlvinfo_header(eeprom_hdr)) {
ret = read_sys_eeprom( pi2c_client, (void *)eeprom_tlv, sizeof(tlvinfo_header_t),
be16_to_cpu(eeprom_hdr->totallen));
}
// If the contents are invalid, start over with default contents
if(!is_valid_tlvinfo_header(eeprom_hdr))
printk(KERN_ERR
"Notice: Invalid TLV header found. Using default contents--1.\n");
if(!is_checksum_valid(eeprom))
printk(KERN_ERR
"Notice: Invalid TLV checksum found. Using default contents--2.\n");
if ( !is_valid_tlvinfo_header(eeprom_hdr) || !is_checksum_valid(eeprom) ){
strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING);
eeprom_hdr->version = TLV_INFO_VERSION;
eeprom_hdr->totallen = cpu_to_be16(0);
update_crc(eeprom);
}
has_been_read = 1;
return ret;
}
EXPORT_SYMBOL(read_eeprom);
/*
* prog_eeprom
* Write the EEPROM data from CPU memory to the hardware.
*/
int prog_eeprom(struct i2c_client *pi2c_client, u_int8_t * eeprom)
{
int ret = 0;
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
int eeprom_len;
eeprom_len = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
ret = write_sys_eeprom( pi2c_client, eeprom, eeprom_len);
if (ret) {
printk("Programming failed.\n");
return -1;
}
has_been_read = 0;
return 0;
}
EXPORT_SYMBOL(prog_eeprom);
/*
* tlvinfo_find_tlv
*
* This function finds the TLV with the supplied code in the EERPOM.
* An offset from the beginning of the EEPROM is returned in the
* eeprom_index parameter if the TLV is found.
*/
bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode,
int *eeprom_index)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
int eeprom_end;
// Make sure the EEPROM contents are valid
if (!is_valid_tlvinfo_header(eeprom_hdr) || !is_checksum_valid(eeprom)) {
return(FALSE);
}
// Search through the TLVs, looking for the first one which matches the
// supplied type code.
*eeprom_index = sizeof(tlvinfo_header_t);
eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
while (*eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index];
if (!is_valid_tlv(eeprom_tlv)) {
return(FALSE);
}
if (eeprom_tlv->type == tcode) {
return(TRUE);
}
*eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
return(FALSE);
}
/*
* tlvinfo_decode_tlv
*
* This function finds the TLV with the supplied code in the EERPOM
* and decodes the value into the buffer provided.
*/
bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, char* value)
{
int eeprom_index;
tlvinfo_tlv_t * eeprom_tlv;
// Find the TLV and then decode it
if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
decode_tlv_value(eeprom_tlv, value);
return TRUE;
}
return FALSE;
}
EXPORT_SYMBOL(tlvinfo_decode_tlv);
/*
* tlvinfo_delete_tlv
*
* This function deletes the TLV with the specified type code from the
* EEPROM.
*/
bool tlvinfo_delete_tlv(u_int8_t * eeprom, u_int8_t code)
{
int eeprom_index;
int tlength;
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
// Find the TLV and then move all following TLVs "forward"
if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
tlength = sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index+tlength],
sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen) -
eeprom_index - tlength);
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) -
tlength);
update_crc(eeprom);
return(TRUE);
}
return(FALSE);
}
EXPORT_SYMBOL(tlvinfo_delete_tlv);
/*
* tlvinfo_add_tlv
*
* This function adds a TLV to the EEPROM, converting the value (a string) to
* the format in which it will be stored in the EEPROM.
*/
#define MAX_TLV_VALUE_LEN 256
bool tlvinfo_add_tlv(u_int8_t * eeprom, int tcode, char * strval)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
int new_tlv_len = 0;
u_int32_t value;
char data[MAX_TLV_VALUE_LEN];
int eeprom_index;
int max_size = TLV_TOTAL_LEN_MAX;
// Encode each TLV type into the format to be stored in the EERPOM
switch (tcode) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
strncpy(data, strval, MAX_TLV_VALUE_LEN);
if( strlen(strval) >= MAX_TLV_VALUE_LEN )
new_tlv_len = MAX_TLV_VALUE_LEN;
else
new_tlv_len = strlen(strval);
break;
case TLV_CODE_DEVICE_VERSION:
value = strtoul(strval, NULL, 0);
if (value >= 256) {
printk("ERROR: Device version must be 255 or less. Value " \
"supplied: %u", value);
return(FALSE);
}
data[0] = value & 0xFF;
new_tlv_len = 1;
break;
case TLV_CODE_MAC_SIZE:
value = strtoul(strval, NULL, 0);
if (value >= 65536) {
printk("ERROR: MAC Size must be 65535 or less. Value " \
"supplied: %u", value);
return(FALSE);
}
data[0] = (value >> 8) & 0xFF;
data[1] = value & 0xFF;
new_tlv_len = 2;
break;
case TLV_CODE_MANUF_DATE:
if (set_date(data, strval) != 0) {
return(FALSE);
}
new_tlv_len = 19;
break;
case TLV_CODE_MAC_BASE:
if (set_mac(data, strval) != 0) {
return(FALSE);
}
new_tlv_len = 6;
break;
case TLV_CODE_CRC_32:
printk("WARNING: The CRC TLV is set automatically and cannot be set " \
"manually.\n");
return(FALSE);
case TLV_CODE_VENDOR_EXT:
default:
if (set_bytes(data, strval, &new_tlv_len) != 0 ) {
return(FALSE);
}
break;
}
// Is there room for this TLV?
if ((be16_to_cpu(eeprom_hdr->totallen) + sizeof(tlvinfo_tlv_t) +
new_tlv_len) > max_size) {
printk("ERROR: There is not enough room in the EERPOM to save data.\n");
return(FALSE);
}
// Add TLV at the end, overwriting CRC TLV if it exists
if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) {
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen)
- sizeof(tlvinfo_tlv_t) - 4);
} else {
eeprom_index = sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen);
}
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
eeprom_tlv->type = tcode;
eeprom_tlv->length = new_tlv_len;
memcpy(eeprom_tlv->value, data, new_tlv_len);
// Update the total length and calculate (add) a new CRC-32 TLV
eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) +
sizeof(tlvinfo_tlv_t) + new_tlv_len);
update_crc(eeprom);
return(TRUE);
}
EXPORT_SYMBOL(tlvinfo_add_tlv);
/*
* read_sys_eeprom - read the hwinfo from i2c EEPROM
*/
int read_sys_eeprom(struct i2c_client *pi2c_client,void *eeprom_data, int offset, int len)
{
int iRet = 0;
int i = 0;
unsigned char ucBuf[2];
u_int8_t *c;
unsigned short usAddr = SYS_EEPROM_OFFSET + offset;
c = eeprom_data;
for (i = 0; i < len; i++) {
ucBuf[0] = (usAddr & 0xFF00) >> 8;
ucBuf[1] = (usAddr & 0x00FF);
iRet = i2c_smbus_write_byte_data(pi2c_client, ucBuf[0], ucBuf[1]);
if( iRet < 0 ){
printk(KERN_ERR"Error!! VPD data read error\n");
return -1;
}
*c = i2c_smbus_read_byte(pi2c_client);
c++; usAddr++;
}
return 0;
}
/*
* write_sys_eeprom - write the hwinfo to i2c EEPROM
*/
int write_sys_eeprom(struct i2c_client *pi2c_client, void *eeprom_data, int len)
{
int iRet = 0;
int i = 0;
u_int8_t *c;
unsigned short usAddr = SYS_EEPROM_OFFSET;
unsigned char ucBuf[3];
c = eeprom_data;
for (i = 0; i < len; i++) {
ucBuf[ 0 ] = (usAddr & 0xFF00) >>8 ;
ucBuf[ 1 ] = (usAddr & 0x00FF);
ucBuf[ 2 ] = *c;
iRet = i2c_smbus_write_word_data( pi2c_client, ucBuf[0], (ucBuf[2] << 8 | ucBuf[1]));
if (iRet < 0 ){
printk(KERN_ERR"Error!! VPD data write error . \n");
return -1;
}
c++; usAddr++;
msleep_interruptible(10);
}
return 0;
}
void update_eeprom_header(u_int8_t *eeprom)
{
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING);
eeprom_hdr->version = TLV_INFO_VERSION;
eeprom_hdr->totallen = cpu_to_be16(0);
update_crc(eeprom);
}
#if 0
int find_vpd_data(u_int8_t *eeprom, int i_offset, char *c_buf)
{
int tlv_end;
int curr_tlv;
tlvinfo_header_t * eeprom_hdr = (tlvinfo_header_t *) eeprom;
tlvinfo_tlv_t * eeprom_tlv;
int iFind = 0;
if( !is_valid_tlvinfo_header(eeprom_hdr) ) {
printk(KERN_ERR"EEPROM does not contain data in a valid TlvInfo format.\n");
return -1;
}
curr_tlv = sizeof(tlvinfo_header_t);
tlv_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
while(curr_tlv < tlv_end){
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[curr_tlv];
if (!is_valid_tlv(eeprom_tlv)) {
printk(KERN_ERR"Invalid TLV field starting at EEPROM offset %d\n",
curr_tlv);
return -1;
}
decode_tlv_value(eeprom_tlv, c_buf);
if( eeprom_tlv->type == i_offset){
iFind = 1;
break;
}
curr_tlv += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
if( iFind == 0 )
return -1;
else
return 0;
}
#endif

View File

@@ -0,0 +1,150 @@
/*
* The Definition of the TlvInfo EEPROM format can be found at onie.org or
* github.com/onie
*/
#include <linux/types.h>
#define strtoul simple_strtoul
#define FALSE 0
#define TRUE (!FALSE)
#define MAX_STRING_SIZE 128
/*
* Tlvinf header: Layout of the header for the TlvInfo format
*
* See the end of this file for details of this eeprom format
*/
struct __attribute__ ((__packed__)) tlvinfo_header_s {
char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */
u_int8_t version; /* 0x08 Structure version */
u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */
};
typedef struct tlvinfo_header_s tlvinfo_header_t;
// Header Field Constants
#define TLV_INFO_ID_STRING "TlvInfo"
#define TLV_INFO_VERSION 0x01
#define TLV_TOTAL_LEN_MAX (SYS_EEPROM_SIZE - sizeof(tlvinfo_header_t))
/*
* TlvInfo TLV: Layout of a TLV field
*/
struct __attribute__ ((__packed__)) tlvinfo_tlv_s {
u_int8_t type;
u_int8_t length;
u_int8_t value[0];
};
typedef struct tlvinfo_tlv_s tlvinfo_tlv_t;
/* Maximum length of a TLV value in bytes */
#define TLV_VALUE_MAX_LEN 255
/**
* The TLV Types.
*
* Keep these in sync with tlv_code_list in cmd_sys_eeprom.c
*/
#define TLV_CODE_PRODUCT_NAME 0x21
#define TLV_CODE_PART_NUMBER 0x22
#define TLV_CODE_SERIAL_NUMBER 0x23
#define TLV_CODE_MAC_BASE 0x24
#define TLV_CODE_MANUF_DATE 0x25
#define TLV_CODE_DEVICE_VERSION 0x26
#define TLV_CODE_LABEL_REVISION 0x27
#define TLV_CODE_PLATFORM_NAME 0x28
#define TLV_CODE_ONIE_VERSION 0x29
#define TLV_CODE_MAC_SIZE 0x2A
#define TLV_CODE_MANUF_NAME 0x2B
#define TLV_CODE_MANUF_COUNTRY 0x2C
#define TLV_CODE_VENDOR_NAME 0x2D
#define TLV_CODE_DIAG_VERSION 0x2E
#define TLV_CODE_SERVICE_TAG 0x2F
#define TLV_CODE_VENDOR_EXT 0xFD
#define TLV_CODE_CRC_32 0xFE
/*
* Struct for displaying the TLV codes and names.
*/
struct tlv_code_desc {
u_int8_t m_code;
char* m_name;
};
/*
* List of TLV codes and names.
*/
static const struct tlv_code_desc tlv_code_list[] = {
{ TLV_CODE_PRODUCT_NAME , "Product Name"},
{ TLV_CODE_PART_NUMBER , "Part Number"},
{ TLV_CODE_SERIAL_NUMBER , "Serial Number"},
{ TLV_CODE_MAC_BASE , "Base MAC Address"},
{ TLV_CODE_MANUF_DATE , "Manufacture Date"},
{ TLV_CODE_DEVICE_VERSION , "Device Version"},
{ TLV_CODE_LABEL_REVISION , "Label Revision"},
{ TLV_CODE_PLATFORM_NAME , "Platform Name"},
{ TLV_CODE_ONIE_VERSION , "Loader Version"},
{ TLV_CODE_MAC_SIZE , "MAC Addresses"},
{ TLV_CODE_MANUF_NAME , "Manufacturer"},
{ TLV_CODE_MANUF_COUNTRY , "Country Code"},
{ TLV_CODE_VENDOR_NAME , "Vendor Name"},
{ TLV_CODE_DIAG_VERSION , "Diag Version"},
{ TLV_CODE_SERVICE_TAG , "Service Tag"},
{ TLV_CODE_VENDOR_EXT , "Vendor Extension"},
{ TLV_CODE_CRC_32 , "CRC-32"},
};
static inline const char* tlv_type2name(u_int8_t type)
{
char* name = "Unknown";
int i;
for (i = 0; i < sizeof(tlv_code_list)/sizeof(tlv_code_list[0]); i++) {
if (tlv_code_list[i].m_code == type) {
name = tlv_code_list[i].m_name;
break;
}
}
return name;
}
/*
* The max decode value is currently for the 'raw' type or the 'vendor
* extension' type, both of which have the same decode format. The
* max decode string size is computed as follows:
*
* strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1
*
*/
#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1)
/*
* Each platform must define the following platform-specific macros
* in sys_eeprom_platform.h:
* SYS_EEPROM_SIZE: size of usable eeprom
* SYS_EEPROM_I2C_DEVICE: i2c-bus
* SYS_EEPROM_I2C_ADDR: address on the bus
* The following may also be defined in sys_eeprom_platform.h, else
* the defaults with take over:
* SYS_EEPROM_MAX_SIZE: Total size of the eeprom
* SYS_EEPROM_OFFSET: offset from where the ONIE header starts
*/
#define SYS_EEPROM_MAX_SIZE 2048
#define SYS_EEPROM_OFFSET 0
#define SYS_EEPROM_SIZE SYS_EEPROM_MAX_SIZE
#define SYS_EEPROM_I2C_DEVICE "/dev/i2c-0"
#define SYS_EEPROM_I2C_ADDR 0x53
#if (SYS_EEPROM_SIZE + SYS_EEPROM_OFFSET > SYS_EEPROM_MAX_SIZE)
#error SYS_EEPROM_SIZE + SYS_EEPROM_OFFSET is greater than SYS_EEPROM_MAX_SIZE
#endif
// Access functions to onie_tlvinfo
void show_eeprom(u_int8_t *eeprom);
int read_eeprom(struct i2c_client *pi2c_client, u_int8_t *eeprom);
int prog_eeprom(struct i2c_client *pi2c_client,u_int8_t * eeprom);
void update_eeprom_header(u_int8_t *eeprom);
bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode, int *eeprom_index);
bool tlvinfo_delete_tlv(u_int8_t * eeprom, u_int8_t code);
bool tlvinfo_add_tlv(u_int8_t * eeprom, int tcode, char * strval);
bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, char* value);
//int find_vpd_data(u_int8_t *eeprom, int i_offset, char *c_buf);

View File

@@ -0,0 +1,811 @@
/*************************************************************************
*
* transceiver.h
*
* 2018 Inventec Corporation
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Inventec Corp. and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Inventec Corporation and its suppliers
* and may be covered by U.S. and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
*
************************************************************************/
#ifndef TRANSCEIVER_H
#define TRANSCEIVER_H
#include <linux/types.h>
/* advanced features control */
#define TRANSVR_INFO_DUMP_ENABLE (1)
#define TRANSVR_INFO_CACHE_ENABLE (1)
#define TRANSVR_UEVENT_ENABLE (1)
/* Transceiver type define */
#define TRANSVR_TYPE_UNKNOW_1 (0x00)
#define TRANSVR_TYPE_UNKNOW_2 (0xff)
#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */
#define TRANSVR_TYPE_QSFP (0x0c)
#define TRANSVR_TYPE_QSFP_PLUS (0x0d)
#define TRANSVR_TYPE_QSFP_28 (0x11)
#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */
#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */
#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */
#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */
/* Transceiver class for base info */
#define TRANSVR_CLASS_UNSPECIFIED (0)
#define TRANSVR_CLASS_ERROR (-26001)
#define TRANSVR_CLASS_1G (26001)
#define TRANSVR_CLASS_10G (26011)
#define TRANSVR_CLASS_25G (26021)
#define TRANSVR_CLASS_40G (26041)
#define TRANSVR_CLASS_100G (26101)
#define TRANSVR_CLASS_NO_SPERARABLE (26901)
#define TRANSVR_CLASS_EXTEND_COMP (26902)
/* Transceiver class for Optical 1G */
#define TRANSVR_CLASS_OPTICAL (27000)
#define TRANSVR_CLASS_OPTICAL_100 (27001)
#define TRANSVR_CLASS_OPTICAL_1G (27002)
#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003)
#define TRANSVR_CLASS_OPTICAL_1G_SX (27004)
#define TRANSVR_CLASS_OPTICAL_1G_LX (27005)
#define TRANSVR_CLASS_OPTICAL_1G_EX (27006)
/* Transceiver class for Optical 10G */
#define TRANSVR_CLASS_OPTICAL_10G (27010)
#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011)
#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012)
#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013)
#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014)
#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015)
#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016)
#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017)
#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018)
/* Transceiver class for Optical 25G */
#define TRANSVR_CLASS_OPTICAL_25G (27020)
#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021)
#define TRANSVR_CLASS_OPTICAL_25G_SR (27022)
#define TRANSVR_CLASS_OPTICAL_25G_LR (27023)
#define TRANSVR_CLASS_OPTICAL_25G_ER (27024)
/* Transceiver class for Optical 40G */
#define TRANSVR_CLASS_OPTICAL_40G (27040)
#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041)
#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042)
#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043)
#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044)
/* Transceiver class for Optical 100G */
#define TRANSVR_CLASS_OPTICAL_100G (27100)
#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101)
#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102)
#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103)
#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104)
#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105)
/* Transceiver class for Copper */
#define TRANSVR_CLASS_COPPER (28000)
#define TRANSVR_CLASS_COPPER_L1_1G (28001)
#define TRANSVR_CLASS_COPPER_L1_10G (28011)
#define TRANSVR_CLASS_COPPER_L4_10G (28012)
#define TRANSVR_CLASS_COPPER_L1_25G (28021)
#define TRANSVR_CLASS_COPPER_L4_40G (28041)
#define TRANSVR_CLASS_COPPER_L4_100G (28101)
/* Transceiver class for Base-T */
#define TRANSVR_CLASS_BASE_T_1000 (29001)
#define TRANSVR_CLASS_BASE_T_1000_up (29002)
/* For uevent message */
#define TRANSVR_UEVENT_KEY_IF "IF_TYPE"
#define TRANSVR_UEVENT_KEY_SP "IF_SPEED"
#define TRANSVR_UEVENT_KEY_LANE "IF_LANE"
#define TRANSVR_UEVENT_UNKNOW "UNKNOW"
#define TRANSVR_IF_KR "KR"
#define TRANSVR_IF_KR4 "KR4"
#define TRANSVR_IF_SR "SR"
#define TRANSVR_IF_SR4 "SR4"
#define TRANSVR_IF_SFI "SFI"
#define TRANSVR_IF_IF_GMII "GMII"
#define TRANSVR_IF_IF_XGMII "XGMII"
#define TRANSVR_IF_SP_100 "100"
#define TRANSVR_IF_SP_1G "1000"
#define TRANSVR_IF_SP_10G "10000"
#define TRANSVR_IF_SP_25G "25000"
#define TRANSVR_IF_SP_40G "40000"
#define TRANSVR_IF_SP_100G "100000"
/* Transceiver mode define */
#define TRANSVR_MODE_DIRECT (21000)
#define TRANSVR_MODE_POLLING (21001)
/* Transceiver state define
* [Note]
* 1. State is used to represent the state of "Transceiver" and "Object".
* 2. State for different target has different means. The description as following:
*/
#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */
#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */
#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */
#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */
#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */
#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */
#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */
/* Task state define */
#define STATE_T_TASK_WAIT (110)
#define STATE_T_TASK_DONE (0)
#define STATE_T_TASK_INIT (-110)
#define STATE_T_TASK_FAIL (-410)
/* Event for task handling */
#define EVENT_TRANSVR_TASK_WAIT (2101)
#define EVENT_TRANSVR_TASK_DONE (0)
#define EVENT_TRANSVR_TASK_FAIL (-2101)
/* Event for initial handling */
#define EVENT_TRANSVR_INIT_UP (2201)
#define EVENT_TRANSVR_INIT_DOWN (1)
#define EVENT_TRANSVR_INIT_REINIT (-2201)
#define EVENT_TRANSVR_INIT_FAIL (-2202)
/* Event for others */
#define EVENT_TRANSVR_RELOAD_FAIL (-2301)
#define EVENT_TRANSVR_EXCEP_INIT (-2401)
#define EVENT_TRANSVR_EXCEP_UP (-2402)
#define EVENT_TRANSVR_EXCEP_DOWN (-2403)
#define EVENT_TRANSVR_EXCEP_SWAP (-2404)
#define EVENT_TRANSVR_EXCEP_EXCEP (-2405)
#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406)
#define EVENT_TRANSVR_I2C_CRASH (-2501)
/* Transceiver error code define */
#define ERR_TRANSVR_UNINIT (-201)
#define ERR_TRANSVR_UNPLUGGED (-202)
#define ERR_TRANSVR_ABNORMAL (-203)
#define ERR_TRANSVR_NOSTATE (-204)
#define ERR_TRANSVR_NOTSUPPORT (-205)
#define ERR_TRANSVR_BADINPUT (-206)
#define ERR_TRANSVR_UPDATE_FAIL (-207)
#define ERR_TRANSVR_RELOAD_FAIL (-208)
#define ERR_TRANSVR_INIT_FAIL (-209)
#define ERR_TRANSVR_UNDEFINED (-210)
#define ERR_TRANSVR_TASK_FAIL (-211)
#define ERR_TRANSVR_TASK_BUSY (-212)
#define ERR_TRANSVR_UEVENT_FAIL (-213)
#define ERR_TRANSVR_FUNC_DISABLE (-214)
#define ERR_TRANSVR_I2C_CRASH (-297)
#define ERR_TRNASVR_BE_ISOLATED (-298)
#define ERR_TRANSVR_UNEXCPT (-299)
/* For debug */
#define DEBUG_TRANSVR_INT_VAL (-99)
#define DEBUG_TRANSVR_HEX_VAL (0xfe)
#define DEBUG_TRANSVR_STR_VAL "ERROR"
/* For system internal */
#define VAL_TRANSVR_COMID_ARREESS (0x50)
#define VAL_TRANSVR_COMID_OFFSET (0x00)
#define VAL_TRANSVR_8472_READY_ADDR (0x51)
#define VAL_TRANSVR_8472_READY_PAGE (-1)
#define VAL_TRANSVR_8472_READY_OFFSET (110)
#define VAL_TRANSVR_8472_READY_BIT (0)
#define VAL_TRANSVR_8472_READY_VALUE (0)
#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff)
#define VAL_TRANSVR_8436_READY_ADDR (0x50)
#define VAL_TRANSVR_8436_READY_PAGE (-1)
#define VAL_TRANSVR_8436_READY_OFFSET (2)
#define VAL_TRANSVR_8436_READY_BIT (0)
#define VAL_TRANSVR_8436_READY_VALUE (0)
#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff)
#define VAL_TRANSVR_8436_PWD_ADDR (0x50)
#define VAL_TRANSVR_8436_PWD_PAGE (-1)
#define VAL_TRANSVR_8436_PWD_OFFSET (123)
#define VAL_TRANSVR_PAGE_FREE (-99)
#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127)
#define VAL_TRANSVR_PAGE_SELECT_DELAY (5)
#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999)
#define VAL_TRANSVR_FUNCTION_DISABLE (-1)
#define STR_TRANSVR_SFP "SFP"
#define STR_TRANSVR_QSFP "QSFP"
#define STR_TRANSVR_QSFP_PLUS "QSFP+"
#define STR_TRANSVR_QSFP28 "QSFP28"
/* For transvr buf len */
#define LEN_TRANSVR_S_STR (16)
#define LEN_TRANSVR_M_STR (32)
#define LEN_TRANSVR_L_STR (64)
/* Optical wavelength */
#define VAL_OPTICAL_WAVELENGTH_SR (850)
#define VAL_OPTICAL_WAVELENGTH_LR (1310)
#define VAL_OPTICAL_WAVELENGTH_ER (1550)
/* BCM chip type define */
#define BCM_CHIP_TYPE_TRIDENT_2 (31001) /* Magnolia, Hudson32i, Spruce */
#define BCM_CHIP_TYPE_TOMAHAWK (31002) /* Redwood, Cypress */
/* Info from transceiver EEPROM */
struct eeprom_map_s {
int addr_br; int page_br; int offset_br; int length_br;
int addr_cdr; int page_cdr; int offset_cdr; int length_cdr;
int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev;
int addr_connector; int page_connector; int offset_connector; int length_connector;
int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type;
int addr_extbr; int page_extbr; int offset_extbr; int length_extbr;
int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id;
int addr_id; int page_id; int offset_id; int length_id;
int addr_eeprom; int page_eeprom; int offset_eeprom; int length_eeprom;
int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm;
int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf;
int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1;
int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2;
int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3;
int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4;
int addr_option; int page_option; int offset_option; int length_option;
int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id;
int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am;
int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em;
int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los;
int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power;
int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0;
int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1;
int addr_temp; int page_temp; int offset_temp; int length_temp;
int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp;
int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext;
int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias;
int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable;
int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq;
int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault;
int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power;
int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name;
int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn;
int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev;
int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn;
int addr_voltage; int page_voltage; int offset_voltage; int length_voltage;
int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength;
};
struct transvr_worker_s;
/* Class of transceiver object */
struct transvr_obj_s {
/* ========== Object private property ==========
* [Prop]: id
* [Desc]: Type of serial transceiver.
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h
*/
uint8_t id;
/* [Prop]: connector
* [Desc]: Connector type.
* [Note]: SFP : A0h / 2
* QSFP: 00h / 130
*/
uint8_t connector;
/* [Prop]: transvr_comp
* [Desc]: Transceiver compliance code.
* [Note]: SFP: SFF-8472
* - Normal : A0h / offset 3-10
* - Extended: A0h / offset 36
* QSFP: SFF-8436 & SFF-8636
* - Normal : 00h / offset 131-138
* - Extended: 00h / offset 192
*/
uint8_t transvr_comp[8];
uint8_t transvr_comp_ext;
/* [Prop]: vendor_name
* [Desc]: SFP vendor name (ASCII 16 byte char).
* [Note]: ex:FINISAR CORP.
*/
char *vendor_name;
/* [Prop]: vendor_pn
* [Desc]: Part number provided by SFP vendor (ASCII 16 byte char).
* [Note]:
*/
char *vendor_pn;
/* [Prop]: vendor_rev
* [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char).
* [Note]:
*/
char *vendor_rev;
/* [Prop]: vendor_sn
* [Desc]: Serial number provided by vendor (ASCII 16 byte char).
* [Note]:
*/
char *vendor_sn;
/* [Prop]: Extended identifier
* [Desc]: SFP:
* => None
*
* QSFP:
* => This byte contained two information:
* (1) Power consumption class
* (2) CDR function present
* [Note]: Bit description as below:
* [SFP]
* None
*
* [QSFP]
* (1) Power consumption class:
* Class 1: 1.5W (Bit6-7 = 00:)
* Class 2: 2.0W (Bit6-7 = 01:)
* Class 3: 2.5W (Bit6-7 = 10:)
* Class 4: 3.5W (Bit6-7 = 11:)
* Class 5: 4.0W (Bit0-1 = 01:)
* Class 6: 4.5W (Bit0-1 = 10:)
* Class 7: 5.0W (Bit0-1 = 11:)
* (2) CDR function present:
* Bit2: 0 = No CDR in RX
* 1 = CDR present in RX
* Bit3: 0 = No CDR in TX
* 1 = CDR present in TX
*/
uint8_t ext_id;
/* [Prop]: br
* [Desc]: Nominal bit rate, units of 100 MBits/sec.
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh
* has val: 0x67
* no val :
*/
uint8_t br;
/* [Prop]: extbr
* [Desc]: Extended br (00h/222)
* [Desc]: Nominal bit rate per channel, units of 250 Mbps.
* Complements. Byte 140. See Table 32A.
*/
uint8_t extbr;
/* [Prop]: len_sm
* [Desc]: Length (single mode)-(100's)m
* [Note]: This value specifies the link length that is supported by the transceiver
* while operating in compliance with the applicable standards using single mode
* fiber. The value is in units of 100 meters. A value of 255 means that the
* transceiver supports a link length greater than 25.4 km. A value of zero means
* that the transceiver does not support single mode fiber or that the length
* information must be determined from the transceiver technology.
*/
int len_sm;
/* [Prop]: len_smf
* [Desc]: Length (single mode)-km
* [Note]: Addition to EEPROM data from original GBIC definition. This value specifies
* the link length that is supported by the transceiver while operating in
* compliance with the applicable standards using single mode fiber. The value
* is in units of kilometers. A value of 255 means that the transceiver supports
* a link length greater than 254 km. A value of zero means that the transceiver
* does not support single mode fiber or that the length information must be
* determined from the transceiver technology.
*/
int len_smf;
/* [Prop]: len_om1
* [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m
* [Note]: The value is in units of 10 meters. A value of 255 means that the
* transceiver supports a link length greater than 2.54 km. A value of
* zero means that the transceiver does not support 50 micron multi-mode
* fiber or that the length information must be determined from the transceiver
* technology.
*/
int len_om1;
/* [Prop]: len_om2
* [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m
* [Note]: The value is in units of 10 meters. A value of 255 means that the
* transceiver supports a link length greater than 2.54 km. A value of
* zero means that the transceiver does not support 50 micron multi-mode
* fiber or that the length information must be determined from the transceiver
* technology.
*/
int len_om2;
/* [Prop]: len_om3
* [Desc]: Length (50um, OM3)
* [Note]: This value specifies link length that is supported by the transceiver while
* operating in compliance with applicable standards using 50 micron multimode
* OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255
* means that the transceiver supports a link length greater than 2.54 km. A value
* of zero means that the transceiver does not support 50 micron multimode fiber
* or that the length information must be determined from the transceiver technology.
*/
int len_om3;
/* [Prop]: len_om4
* [Desc]: Length (50um, OM4) and Length (Active Cable or Copper)
* [Note]: For optical links, this value specifies link length that is supported by the
* transceiver while operating in compliance with applicable standards using 50 micron
* multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of
* 255 means that the transceiver supports a link length greater than 2.54 km. A value
* of zero means that the transceiver does not support 50 micron multimode fiber or that
* the length information must be determined from the transceiver codes specified in Table 5-3.
*
* For copper links, this value specifies minimum link length supported by the transceiver
* while operating in compliance with applicable standards using copper cable. For active
* cable, this value represents actual length. The value is in units of 1 meter. A value of 255
* means the transceiver supports a link length greater than 254 meters. A value of zero means
* the transceiver does not support copper or active cables or the length information must be
* determined from transceiver technology. Further information about cable design, equalization,
* and connectors is usually required to guarantee meeting a particular length requirement.
*/
int len_om4;
/* [Prop]: comp_rev
* [Desc]: SFF spec revision compliance
* [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver
* complies with. (unsigned integer)
*/
uint8_t comp_rev;
/* [Prop]: CDR
* [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal
* retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which
* directs traffic around the internal CDR. (Reference: SFF-8636)
* [Note]: value=0xff: ON.
* value=0x00: OFF.
*/
uint8_t cdr;
/* [Prop]: rate_id
* [Desc]: Soft Rate Select 0(RX).
* [Note]: 1. Addr: A0h / Offset: 13
* 2. Value description:
* 00h Unspecified
* 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1)
* 02h SFF-8431 (8/4/2G Rx Rate_Select only)
* 03h Unspecified *
* 04h SFF-8431 (8/4/2G Tx Rate_Select only)
* 05h Unspecified *
* 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select)
* 07h Unspecified *
* 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G
* 09h Unspecified *
* 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only,
* Low=8G/4G
* 0Bh Unspecified *
* 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)
* High=32G only, Low = 16G/8G
* 0Dh Unspecified *
* 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking
* modes of the internal signal conditioner, retimer or CDR, according
* to the logic table defined in Table 10-2, High Bit Rate
* (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode,
* the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11)
* and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1.
* 0Fh Unspecified *
* 10h-FFh Unallocated
*/
int rate_id;
/* [Prop]: soft_rs0
* [Desc]: Soft Rate Select 0(RX).
* [Note]: 1. Writing '1' selects full bandwidth operation.
* 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value.
* 3. Default at power up is logic zero/low
* 4. Addr: A2h / Offset: 110 / Bit: 3
*/
uint8_t soft_rs0;
/* [Prop]: soft_rs1
* [Desc]: Soft Rate Select 1(TX).
* [Note]: 1. Writing '1' selects full bandwidth TX operation.
* 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value.
* 3. Default at power up is logic zero/low
* 4. Addr: A2h / Offset: 118 / Bit: 3
*/
uint8_t soft_rs1;
/* [Prop]: diag_type
* [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92)
* [Note]: Description in SFF-8472 as below:
* Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance
* with this document.
* Bit6: Digital diagnostic monitoring implemented (described in this document).
* Must be '1' for compliance with this document.
* Bit5 Internally calibrated
* Bit4 Externally calibrated
* Bit3 Received power measurement type.0 = OMA, 1 = average power
* Bit2 Address change required see section above, "addressing modes"
* Bit1-0 Unallocated
*/
uint8_t diag_type;
/* [Prop]: curr_temp
* [Desc]: Transceiver Current Temperature (A2h/96-97)
* [Note]: 1. Dependent on diag_type.
* 2. 96: High byte
* 3. 97: Low byte
* 4. This feature only for SFP
*/
uint8_t curr_temp[2];
/* [Prop]: curr_vol
* [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23)
* [Note]: 1. Dependent on diag_type.
* 2. 98: High byte
* 3. 99: Low byte
* 4. This feature only for SFP
* 5. Internally measured transceiver supply voltage. Represented
* as a 16 bit unsigned integer with the voltage defined as the
* full 16 bit value (0-65535) with LSB equal to 100 uVolt,
* yielding a total range of 0 to +6.55 Volts
*/
uint8_t curr_voltage[2];
/* [Prop]: curr_tx_bias
* [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27)
* [Note]: 1. Dependent on diag_type.
* 2. 100: High byte
* 3. 101: Low byte
* 4. This feature only for SFP
* 5. Measured TX bias current in uA. Represented as a 16 bit unsigned
* integer with the current defined as the full 16 bit value (0-65535)
* with LSB equal to 2 uA, yielding a total range of 0 to 131 mA.
* Accuracy is vendor specific but must be better than 10% of the
* manufacturer's nominal value over specified operating temperature
* and voltage.
*/
uint8_t curr_tx_bias[8];
/* [Prop]: curr_tx_power
* [Desc]: Transceiver TX Output Power (A2h/102-103)
* [Note]: 1. Dependent on diag_type.
* 2. 102: High byte
* 3. 103: Low byte
* 4. This feature only for SFP
* 5. Measured TX output power in mW. Represented as a 16 bit unsigned
* integer with the power defined as the full 16 bit value (0-65535)
* with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW
* (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of
* laser monitor photodiode current. It is factory calibrated to absolute
* units using the most representative fiber output type. Accuracy is
* vendor specific but must be better than 3dB over specified temperature
* and voltage. Data is not valid when the transmitter is disabled.
*/
uint8_t curr_tx_power[8];
/* [Prop]: curr_tx_power
* [Desc]: Transceiver TX Output Power (A2h/102-103)
* [Note]: 1. Dependent on diag_type.
* 2. 102: High byte
* 3. 103: Low byte
* 4. This feature only for SFP
* 5. Measured RX received optical power in mW. Value can represent either
* average received power or OMA depending upon how bit 3 of byte 92 (A0h)
* is set. Represented as a 16 bit unsigned integer with the power defined
* as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a
* total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is
* dependent upon the exact optical wavelength. For the vendor specified
* wavelength, accuracy shall be better than 3dB over specified temperature
* and voltage.
*/
uint8_t curr_rx_power[8];
/* [Prop]: wavelength
* [Desc]: Wavelength or Copper Cable Attenuation
* [Note]: (Following is info from SFF-8636)
* For optical free side devices, this parameter identifies the nominal
* transmitter output wavelength at room temperature. This parameter is a
* 16-bit hex value with Byte 186 as high order byte and Byte 187 as low
* order byte. The laser wavelength is equal to the 16-bit integer value
* divided by 20 in nm (units of 0.05 nm). This resolution should be adequate
* to cover all relevant wavelengths yet provide enough resolution for all
* expected DWDM applications. For accurate representation of controlled
* wavelength applications, this value should represent the center of the
* guaranteed wavelength range. If the free side device is identified as
* copper cable these registers will be used to define the cable attenuation.
* An indication of 0 dB attenuation refers to the case where the attenuation
* is not known or is unavailable.
* Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB.
* Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB.
*/
uint8_t wavelength[2];
/* [Prop]: Amplitude control
* [Desc]: Amplitude control
* [Note]: QSFP28 => SFF-8636 03H Byte-238/239
*/
uint8_t rx_am[2];
/* [Prop]: Emphasis control
* [Desc]: Emphasis control
* [Note]: SFP+/28 => SFF-8472 A2H Byte-115
* QSFP28 => SFF-8636 03H Byte-236/237
*/
uint8_t rx_em[2];
/* [Prop]: Soft Rx LOS
* [Desc]: Soft Rx LOS which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 3:
* - Bit 0: L-Rx1 LOS
* - Bit 1: L-Rx2 LOS
* - Bit 2: L-Rx3 LOS
* - Bit 3: L-Rx4 LOS
*/
uint8_t rx_los;
/* [Prop]: Soft Tx Disable
* [Desc]: Soft Tx Disable which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 86:
* - Bit 0: Tx1 Disable
* - Bit 1: Tx2 Disable
* - Bit 2: Tx3 Disable
* - Bit 3: Tx4 Disable
*/
uint8_t tx_disable;
/* [Prop]: Soft Tx Fault
* [Desc]: Soft Tx Fault which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 86:
* - Bit 0: Tx1 Fault
* - Bit 1: Tx2 Fault
* - Bit 2: Tx3 Fault
* - Bit 3: Tx4 Fault
*/
uint8_t tx_fault;
/* [Prop]: Transceiver EQUALIZATION
* [Desc]: Transceiver EQUALIZATION
* [Note]: SFP+/28 => SFF-8472 A2H Byte-114
* QSFP28 => SFF-8636 03H Byte-234/235
*/
uint8_t tx_eq[2];
/* [Prop]: OPTION VALUES
* [Desc]: The bits in the option field shall specify the options implemented in the transceiver.
* [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65
* QSFP+/28 => SFF-8636 00H Byte-193/195
*/
uint8_t option[3];
uint8_t eeprom[256];
/* ========== Object private property ==========
*/
struct device *transvr_dev_p;
struct eeprom_map_s *eeprom_map_p;
struct i2c_client *i2c_client_p;
struct ioexp_obj_s *ioexp_obj_p;
struct transvr_worker_s *worker_p;
struct mutex lock;
char swp_name[32];
int auto_config;
int auto_tx_disable;
int chan_id;
int chipset_type;
int curr_page;
int info;
int ioexp_virt_offset;
int lane_id[8];
int layout;
int mode;
int retry;
int state;
int temp;
int type;
/* ========== Object public functions ==========
*/
int (*get_id)(struct transvr_obj_s *self);
int (*get_eeprom)(struct transvr_obj_s *self, char *buf_p);
int (*get_ext_id)(struct transvr_obj_s *self);
int (*get_connector)(struct transvr_obj_s *self);
int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p);
int (*get_power_cls)(struct transvr_obj_s *self);
int (*get_br)(struct transvr_obj_s *self);
int (*get_len_sm)(struct transvr_obj_s *self);
int (*get_len_smf)(struct transvr_obj_s *self);
int (*get_len_om1)(struct transvr_obj_s *self);
int (*get_len_om2)(struct transvr_obj_s *self);
int (*get_len_om3)(struct transvr_obj_s *self);
int (*get_len_om4)(struct transvr_obj_s *self);
int (*get_comp_rev)(struct transvr_obj_s *self);
int (*get_comp_eth_1)(struct transvr_obj_s *self);
int (*get_comp_eth_10)(struct transvr_obj_s *self);
int (*get_comp_eth_10_40)(struct transvr_obj_s *self);
int (*get_comp_extend)(struct transvr_obj_s *self);
int (*get_cdr)(struct transvr_obj_s *self);
int (*get_rate_id)(struct transvr_obj_s *self);
int (*get_soft_rs0)(struct transvr_obj_s *self);
int (*get_soft_rs1)(struct transvr_obj_s *self);
int (*get_info)(struct transvr_obj_s *self);
int (*get_if_type)(struct transvr_obj_s *self, char *buf_p);
int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p);
int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p);
int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p);
int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p);
int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p);
int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p);
int (*set_cdr)(struct transvr_obj_s *self, int input_val);
int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val);
int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val);
int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val);
int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val);
int (*set_tx_eq)(struct transvr_obj_s *self, int input_val);
int (*set_rx_am)(struct transvr_obj_s *self, int input_val);
int (*set_rx_em)(struct transvr_obj_s *self, int input_val);
/* ========== Object private functions ==========
*/
int (*init)(struct transvr_obj_s *self);
int (*clean)(struct transvr_obj_s *self);
int (*check)(struct transvr_obj_s *self);
int (*update_all)(struct transvr_obj_s *self, int show_err);
int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name);
int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name);
int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action);
int (*dump_all)(struct transvr_obj_s* self);
};
/* For AVL Mapping */
struct transvr_avl_s {
char vendor_name[32];
char vendor_pn[32];
int (*init)(struct transvr_obj_s *self);
};
/* Worker for long term task of transceiver */
struct transvr_worker_s {
/* Task Parameter */
struct transvr_obj_s *transvr_p;
struct transvr_worker_s *next_p;
struct transvr_worker_s *pre_p;
unsigned long trigger_time;
char func_name[64];
int retry;
int state;
/* Task private data */
void *p_data;
/* Call back function */
int (*main_task)(struct transvr_worker_s *task);
int (*post_task)(struct transvr_worker_s *task);
};
struct transvr_obj_s *
create_transvr_obj(char *swp_name,
int chan_id,
struct ioexp_obj_s *ioexp_obj_p,
int ioexp_virt_offset,
int transvr_type,
int chipset_type,
int run_mode);
void lock_transvr_obj(struct transvr_obj_s *self);
void unlock_transvr_obj(struct transvr_obj_s *self);
int isolate_transvr_obj(struct transvr_obj_s *self);
int resync_channel_tier_2(struct transvr_obj_s *self);
void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg);
#endif /* TRANSCEIVER_H */

View File

@@ -1 +0,0 @@
libonlp-x86-64-inventec-d7054q28b.mk

View File

@@ -1 +0,0 @@
x86_64_inventec_d7054q28b.mk

View File

@@ -1,36 +1,21 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* fani.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Fan Platform Implementation Defaults.
*
***********************************************************/
#include <stdlib.h>
#include <onlplib/file.h>
#include <onlp/platformi/fani.h>
#include <onlplib/mmap.h>
#include <fcntl.h>
#include "platform_lib.h"
#define PREFIX_PATH_ON_MAIN_BOARD "/sys/bus/i2c/devices/2-0066/"
#define PREFIX_PATH_ON_PSU "/sys/bus/i2c/devices/"
#define FAN_GPI_ON_MAIN_BOARD INV_PSOC_PREFIX"/fan_gpi"
#define MAX_FAN_SPEED 18000
#define MAX_PSU_FAN_SPEED 25500
@@ -38,41 +23,40 @@
#define PROJECT_NAME
#define LEN_FILE_NAME 80
#define FAN_RESERVED 0
#define FAN_1_ON_MAIN_BOARD 1
#define FAN_2_ON_MAIN_BOARD 2
#define FAN_3_ON_MAIN_BOARD 3
#define FAN_4_ON_MAIN_BOARD 4
#define FAN_5_ON_MAIN_BOARD 5
#define FAN_6_ON_MAIN_BOARD 6
#define FAN_1_ON_PSU1 7
#define FAN_1_ON_PSU2 8
enum fan_id {
FAN_1_ON_FAN_BOARD = 1,
FAN_2_ON_FAN_BOARD,
FAN_3_ON_FAN_BOARD,
FAN_4_ON_FAN_BOARD,
FAN_5_ON_FAN_BOARD,
FAN_1_ON_PSU_1,
FAN_1_ON_PSU_2,
FAN_RESERVED,
FAN_1_ON_MAIN_BOARD,
FAN_2_ON_MAIN_BOARD,
FAN_3_ON_MAIN_BOARD,
FAN_4_ON_MAIN_BOARD,
FAN_5_ON_MAIN_BOARD,
FAN_6_ON_MAIN_BOARD,
FAN_7_ON_MAIN_BOARD,
FAN_8_ON_MAIN_BOARD,
FAN_1_ON_PSU1,
FAN_1_ON_PSU2,
};
#define _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) \
{ #prj"fan"#id"_present", #prj"fan"#id"_fault", #prj"fan"#id"_front_speed_rpm", \
#prj"fan"#id"_direction", #prj"fan_duty_cycle_percentage", #prj"fan"#id"_rear_speed_rpm" }
#define MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id)
#define MAKE_FAN_PATH_ON_PSU(folder) \
{"", #folder"/psu_fan1_fault", #folder"/psu_fan1_speed_rpm", \
"", #folder"/psu_fan1_duty_cycle_percentage", "" }
static char* devfiles__[CHASSIS_FAN_COUNT+1] = /* must map with onlp_thermal_id */
{
"reserved",
INV_PSOC_PREFIX"/fan1_input",
INV_PSOC_PREFIX"/fan2_input",
INV_PSOC_PREFIX"/fan3_input",
INV_PSOC_PREFIX"/fan4_input",
INV_PSOC_PREFIX"/fan5_input",
INV_PSOC_PREFIX"/fan6_input",
INV_PSOC_PREFIX"/fan7_input",
INV_PSOC_PREFIX"/fan8_input",
INV_PSOC_PREFIX"/rpm_psu1",
INV_PSOC_PREFIX"/rpm_psu2",
};
#define MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(id) \
{ \
{ ONLP_FAN_ID_CREATE(FAN_##id##_ON_MAIN_BOARD), "Chassis Fan "#id, 0 }, \
0x0, \
(ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
(ONLP_FAN_CAPS_F2B | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
@@ -82,7 +66,7 @@ enum fan_id {
{ \
{ ONLP_FAN_ID_CREATE(FAN_##fan_id##_ON_PSU##psu_id), "Chassis PSU-"#psu_id " Fan "#fan_id, 0 }, \
0x0, \
(ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
(ONLP_FAN_CAPS_F2B | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
@@ -97,6 +81,8 @@ onlp_fan_info_t linfo[] = {
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(4),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(5),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(6),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(7),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(8),
MAKE_FAN_INFO_NODE_ON_PSU(1,1),
MAKE_FAN_INFO_NODE_ON_PSU(2,1),
};
@@ -108,78 +94,41 @@ onlp_fan_info_t linfo[] = {
} \
} while(0)
static int
_onlp_fani_info_get_fan(int fid, onlp_fan_info_t* info)
{
int value, ret;
int value, ret;
char vstr[32], *vstrp = vstr, **vp = &vstrp;
/* get fan present status
*/
ret = onlp_file_read_int(&value, "%s""fan%d_present", FAN_BOARD_PATH, fid);
memset(vstr, 0, 32);
/* get fan present status */
ret = onlp_file_read_str(vp, FAN_GPI_ON_MAIN_BOARD);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
sscanf(*vp, "%x", &value);
if (value & (1 << (fid-1))) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
else {
info->status |= ONLP_FAN_STATUS_PRESENT;
info->status |= ONLP_FAN_STATUS_F2B;
}
if (value == 0) {
return ONLP_STATUS_OK;
}
info->status |= ONLP_FAN_STATUS_PRESENT;
/* get fan fault status (turn on when any one fails)
*/
ret = onlp_file_read_int(&value, "%s""fan%d_fault", FAN_BOARD_PATH, fid);
/* get front fan speed */
memset(vstr, 0, 32);
ret = onlp_file_read_str(vp, devfiles__[fid]);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
sscanf(*vp, "%d", &value);
info->rpm = value;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
if (value > 0) {
info->status |= ONLP_FAN_STATUS_FAILED;
}
snprintf(info->model, ONLP_CONFIG_INFO_STR_MAX, "NA");
snprintf(info->serial, ONLP_CONFIG_INFO_STR_MAX, "NA");
/* get fan direction (both : the same)
*/
ret = onlp_file_read_int(&value, "%s""fan%d_direction", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->status |= value ? ONLP_FAN_STATUS_B2F : ONLP_FAN_STATUS_F2B;
/* get front fan speed
*/
ret = onlp_file_read_int(&value, "%s""fan%d_front_speed_rpm", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->rpm = value;
/* get rear fan speed
*/
ret = onlp_file_read_int(&value, "%s""fan%d_rear_speed_rpm", FAN_BOARD_PATH, fid);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
/* take the min value from front/rear fan speed
*/
if (info->rpm > value) {
info->rpm = value;
}
/* get speed percentage from rpm
*/
ret = onlp_file_read_int(&value, "%s""fan_max_speed_rpm", FAN_BOARD_PATH);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
info->percentage = (info->rpm * 100)/value;
return ONLP_STATUS_OK;
return ONLP_STATUS_OK;
}
@@ -212,28 +161,30 @@ _onlp_get_fan_direction_on_psu(void)
static int
_onlp_fani_info_get_fan_on_psu(int pid, onlp_fan_info_t* info)
_onlp_fani_info_get_fan_on_psu(int fid, onlp_fan_info_t* info)
{
int val = 0;
int value, ret;
char vstr[32], *vstrp = vstr, **vp = &vstrp;
info->status |= ONLP_FAN_STATUS_PRESENT;
info->status |= ONLP_FAN_STATUS_PRESENT;
info->status |= ONLP_FAN_STATUS_F2B;
/* get fan direction
*/
/* get fan direction */
info->status |= _onlp_get_fan_direction_on_psu();
/* get fan fault status
*/
if (psu_pmbus_info_get(pid, "psu_fan1_fault", &val) == ONLP_STATUS_OK) {
info->status |= (val > 0) ? ONLP_FAN_STATUS_FAILED : 0;
/* get front fan speed */
memset(vstr, 0, 32);
ret = onlp_file_read_str(vp, devfiles__[fid]);
if (ret < 0) {
return ONLP_STATUS_E_INTERNAL;
}
sscanf(*vp, "%d", &value);
info->rpm = value;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
info->status |= (value == 0) ? ONLP_FAN_STATUS_FAILED : 0;
/* get fan speed
*/
if (psu_pmbus_info_get(pid, "psu_fan1_speed_rpm", &val) == ONLP_STATUS_OK) {
info->rpm = val;
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
}
snprintf(info->model, ONLP_CONFIG_INFO_STR_MAX, "NA");
snprintf(info->serial, ONLP_CONFIG_INFO_STR_MAX, "NA");
return ONLP_STATUS_OK;
}
@@ -260,7 +211,7 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
switch (local_id)
{
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU2:
rc = _onlp_fani_info_get_fan_on_psu(local_id, info);
break;
@@ -270,7 +221,9 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
case FAN_4_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
rc =_onlp_fani_info_get_fan(local_id, info);
case FAN_7_ON_MAIN_BOARD:
case FAN_8_ON_MAIN_BOARD:
rc = _onlp_fani_info_get_fan(local_id, info);
break;
default:
rc = ONLP_STATUS_E_INVALID;
@@ -305,15 +258,18 @@ onlp_fani_percentage_set(onlp_oid_t id, int p)
switch (fid)
{
case FAN_1_ON_PSU_1:
return psu_pmbus_info_set(PSU1_ID, "psu_fan1_duty_cycle_percentage", p);
case FAN_1_ON_PSU_2:
return psu_pmbus_info_set(PSU2_ID, "psu_fan1_duty_cycle_percentage", p);
case FAN_1_ON_FAN_BOARD:
case FAN_2_ON_FAN_BOARD:
case FAN_3_ON_FAN_BOARD:
case FAN_4_ON_FAN_BOARD:
case FAN_5_ON_FAN_BOARD:
case FAN_1_ON_PSU1:
return psu_pmbus_info_set(PSU1_ID, "rpm_psu", p);
case FAN_1_ON_PSU2:
return psu_pmbus_info_set(PSU2_ID, "rpm_psu", p);
case FAN_1_ON_MAIN_BOARD:
case FAN_2_ON_MAIN_BOARD:
case FAN_3_ON_MAIN_BOARD:
case FAN_4_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
case FAN_7_ON_MAIN_BOARD:
case FAN_8_ON_MAIN_BOARD:
path = FAN_NODE(fan_duty_cycle_percentage);
break;
default:

View File

@@ -1,38 +1,21 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* ledi.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/ledi.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include "platform_lib.h"
#define prefix_path "/sys/class/leds/inventec_d7054q28b_led::"
#define filename "brightness"
#define VALIDATE(_id) \
@@ -42,18 +25,27 @@
} \
} while(0)
/* LED related data
*/
/* LED related data */
enum onlp_led_id
{
LED_RESERVED = 0,
LED_DIAG,
LED_LOC,
LED_FAN,
LED_PSU1,
LED_PSU2
LED_SYS,
LED_FAN1,
LED_FAN2,
LED_FAN3,
LED_FAN4
};
static char* devfiles__[CHASSIS_LED_COUNT+1] = /* must map with onlp_thermal_id */
{
"reserved",
INV_CPLD_PREFIX"/%s_led",
INV_PSOC_PREFIX"/fan_led_%s1",
INV_PSOC_PREFIX"/fan_led_%s2",
INV_PSOC_PREFIX"/fan_led_%s3",
INV_PSOC_PREFIX"/fan_led_%s4",
};
enum led_light_mode {
LED_MODE_OFF = 0,
LED_MODE_GREEN,
@@ -75,15 +67,14 @@ typedef struct led_light_mode_map {
} led_light_mode_map_t;
led_light_mode_map_t led_map[] = {
{LED_DIAG, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_DIAG, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_DIAG, LED_MODE_AMBER, ONLP_LED_MODE_ORANGE},
{LED_DIAG, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_LOC, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_LOC, LED_MODE_BLUE, ONLP_LED_MODE_BLUE},
{LED_FAN, LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_PSU1, LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_PSU2, LED_MODE_AUTO, ONLP_LED_MODE_AUTO}
{LED_SYS, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_SYS, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_SYS, LED_MODE_AMBER, ONLP_LED_MODE_ORANGE},
{LED_SYS, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_FAN1,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_FAN2,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_FAN3,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
{LED_FAN4,LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
};
static char last_path[][10] = /* must map with onlp_led_id */
@@ -103,47 +94,37 @@ static onlp_led_info_t linfo[] =
{
{ }, /* Not used */
{
{ ONLP_LED_ID_CREATE(LED_DIAG), "Chassis LED 1 (DIAG LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_SYS), "Chassis LED (SYSTEM LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED | ONLP_LED_CAPS_ORANGE,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_LOC), "Chassis LED 2 (LOC LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN1), "Fan LED 1 (FAN1 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_BLUE,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_FAN), "Chassis LED 3 (FAN LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN2), "Fan LED 2 (FAN2 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_AUTO,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_PSU1), "Chassis LED 4 (PSU1 LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN3), "Fan LED 3 (FAN3 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_AUTO,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
{
{ ONLP_LED_ID_CREATE(LED_PSU2), "Chassis LED 4 (PSU2 LED)", 0 },
{ ONLP_LED_ID_CREATE(LED_FAN4), "Fan LED 4 (FAN4 LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_AUTO,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
ONLP_LED_MODE_ON, '0',
},
};
static int driver_to_onlp_led_mode(enum onlp_led_id id, enum led_light_mode driver_led_mode)
{
int i, nsize = sizeof(led_map)/sizeof(led_map[0]);
for (i = 0; i < nsize; i++)
{
if (id == led_map[i].id && driver_led_mode == led_map[i].driver_led_mode)
{
return led_map[i].onlp_led_mode;
}
}
return 0;
}
static int onlp_to_driver_led_mode(enum onlp_led_id id, onlp_led_mode_t onlp_led_mode)
{
int i, nsize = sizeof(led_map)/sizeof(led_map[0]);
@@ -168,41 +149,113 @@ onlp_ledi_init(void)
/*
* Diag LED Off
*/
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_DIAG), ONLP_LED_MODE_OFF);
onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_SYS), ONLP_LED_MODE_OFF);
return ONLP_STATUS_OK;
}
int onlp_chassis_led_read(char *pathp, char *buf, size_t len)
{
FILE * fp;
fp = fopen (pathp, "r");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
if( fgets (buf, len, fp) == NULL ) {
perror("Error fgets operation");
}
fclose(fp);
return(0);
}
int
onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
{
int local_id;
char data[2] = {0};
char fullpath[50] = {0};
int local_id, gret = 0, rret = 0;
char fullpath_grn[50] = {0};
char fullpath_red[50] = {0};
int gvalue = 0, rvalue = 0;
char buf[32] = {0};
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
/* get fullpath */
sprintf(fullpath, "%s%s/%s", prefix_path, last_path[local_id], filename);
switch (local_id) {
case LED_SYS:
sprintf(fullpath_grn, devfiles__[local_id], "grn");
sprintf(fullpath_red, devfiles__[local_id], "red");
/* Set LED mode */
gret = onlp_chassis_led_read(fullpath_grn, buf, 32);
if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3' || buf[0] == '7') {
gvalue = 1;
}
rret = onlp_chassis_led_read(fullpath_red, buf, 32);
if (buf[0] == '1' || buf[0] == '2' || buf[0] == '3' || buf[0] == '7') {
rvalue = 1;
}
if (gret < 0 && rret < 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
gvalue = -1;
rvalue = -1;
}
break;
case LED_FAN1:
case LED_FAN2:
case LED_FAN3:
case LED_FAN4:
sprintf(fullpath_grn, devfiles__[local_id], "grn");
sprintf(fullpath_red, devfiles__[local_id], "red");
/* Set LED mode */
if (onlp_file_read_int(&gvalue, fullpath_grn) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
gvalue = 0;
}
if (onlp_file_read_int(&rvalue, fullpath_red) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
rvalue = 0;
}
break;
default:
DEBUG_PRINT("%s(%d) Invalid led id %d\r\n", __FUNCTION__, __LINE__, local_id);
gvalue = -1;
rvalue = -1;
break;
}
/* Set the onlp_oid_hdr_t and capabilities */
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[ONLP_OID_ID_GET(id)];
/* Set LED mode */
if (onlp_file_read_string(fullpath, data, sizeof(data), 0) != 0) {
DEBUG_PRINT("%s(%d)\r\n", __FUNCTION__, __LINE__);
return ONLP_STATUS_E_INTERNAL;
if (gvalue == 1 && rvalue == 0) {
info->mode = ONLP_LED_MODE_GREEN;
info->status |= ONLP_LED_STATUS_ON;
}
info->mode = driver_to_onlp_led_mode(local_id, atoi(data));
/* Set the on/off status */
if (info->mode != ONLP_LED_MODE_OFF) {
info->status |= ONLP_LED_STATUS_ON;
else
if (gvalue == 0 && rvalue == 1) {
info->mode = ONLP_LED_MODE_RED;
info->status |= ONLP_LED_STATUS_ON;
}
else
if (gvalue == 1 && rvalue == 1) {
info->mode = ONLP_LED_MODE_ORANGE;
info->status |= ONLP_LED_STATUS_ON;
}
else
if (gvalue == 0 && rvalue == 0) {
info->mode = ONLP_LED_MODE_OFF;
info->status |= ONLP_LED_STATUS_ON;
}
else {
info->mode = ONLP_LED_MODE_OFF;
info->status |= ONLP_LED_STATUS_FAILED;
}
return ONLP_STATUS_OK;
}
@@ -242,7 +295,20 @@ onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
sprintf(fullpath, "%s%s/%s", prefix_path, last_path[local_id], filename);
switch (local_id) {
case LED_SYS:
sprintf(fullpath, "%s%s/%s", INV_CPLD_PREFIX, last_path[local_id], filename);
break;
case LED_FAN1:
case LED_FAN2:
case LED_FAN3:
case LED_FAN4:
sprintf(fullpath, "%s%s/%s", INV_PSOC_PREFIX, last_path[local_id], filename);
break;
default:
DEBUG_PRINT("%s(%d) Invalid led id %d\r\n", __FUNCTION__, __LINE__, local_id);
return ONLP_STATUS_E_INTERNAL;
}
if (onlp_file_write_int(onlp_to_driver_led_mode(local_id, mode), fullpath, NULL) != 0)
{

View File

@@ -1,27 +1,10 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* platform_lib.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <sys/mman.h>
#include <errno.h>
@@ -152,10 +135,14 @@ int psu_pmbus_info_get(int id, char *node, int *value)
*value = 0;
if (PSU1_ID == id) {
ret = onlp_file_read_int(value, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
ret = onlp_file_read_int(value, "%s%s%d", PSU1_AC_PMBUS_PREFIX, node, PSU1_ID);
}
else
if (PSU2_ID == id) {
ret = onlp_file_read_int(value, "%s%s%d", PSU2_AC_PMBUS_PREFIX, node, PSU2_ID);
}
else {
ret = onlp_file_read_int(value, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
return ONLP_STATUS_E_INTERNAL;
}
if (ret < 0) {
@@ -171,10 +158,10 @@ int psu_pmbus_info_set(int id, char *node, int value)
switch (id) {
case PSU1_ID:
sprintf(path, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
sprintf(path, "%s%s%d", PSU1_AC_PMBUS_PREFIX, node, PSU1_ID);
break;
case PSU2_ID:
sprintf(path, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
sprintf(path, "%s%s%d", PSU2_AC_PMBUS_PREFIX, node, PSU2_ID);
break;
default:
return ONLP_STATUS_E_UNSUPPORTED;

View File

@@ -1,61 +1,57 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* platform_lib.h
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __PLATFORM_LIB_H__
#define __PLATFORM_LIB_H__
#include "x86_64_inventec_d7054q28b_log.h"
#define CHASSIS_FAN_COUNT 6
#define CHASSIS_THERMAL_COUNT 5
#define SWPS_CYPRESS_GA2 (1)
#define PSU1_ID 1
#define PSU2_ID 2
#define ONLP_NODE_MAX_INT_LEN (8)
#define ONLP_NODE_MAX_PATH_LEN (64)
#define PSU1_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/11-005b/"
#define PSU2_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/10-0058/"
#define CHASSIS_PSU_COUNT (2)
#define CHASSIS_LED_COUNT (5)
#define CHASSIS_FAN_COUNT (10)
#define CHASSIS_SFP_COUNT (54)
#define CHASSIS_THERMAL_COUNT (14)
#define INV_CPLD_COUNT (1)
#define INV_CPLD_PREFIX "/sys/bus/i2c/devices/0-0055/"
#define INV_PSOC_PREFIX "/sys/bus/i2c/devices/0-0066/"
#define INV_EPRM_PREFIX "/sys/bus/i2c/devices/0-0053/"
#define INV_CTMP_PREFIX "/sys/devices/platform/coretemp.0/hwmon/hwmon0/"
/*
* Definitions of Chassis EEPROM
*/
#define EEPROM_NODE(node) INV_EPRM_PREFIX#node
/*
* Definitions of PSU device
*/
enum onlp_psu_id
{
PSU_RESERVED = 0,
PSU1_ID,
PSU2_ID
};
#define PSU1_AC_PMBUS_PREFIX INV_PSOC_PREFIX
#define PSU2_AC_PMBUS_PREFIX INV_PSOC_PREFIX
#define PSU1_AC_PMBUS_NODE(node) PSU1_AC_PMBUS_PREFIX#node
#define PSU2_AC_PMBUS_NODE(node) PSU2_AC_PMBUS_PREFIX#node
#define PSU1_AC_HWMON_PREFIX "/sys/bus/i2c/devices/11-0053/"
#define PSU2_AC_HWMON_PREFIX "/sys/bus/i2c/devices/10-0050/"
#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node
#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node
#define FAN_BOARD_PATH "/sys/devices/platform/fan/"
#define FAN_NODE(node) FAN_BOARD_PATH#node
#define IDPROM_PATH "/sys/class/i2c-adapter/i2c-1/1-0057/eeprom"
int onlp_file_read_binary(char *filename, char *buffer, int buf_size, int data_len);
int onlp_file_read_string(char *filename, char *buffer, int buf_size, int data_len);
int psu_pmbus_info_get(int id, char *node, int *value);
int psu_pmbus_info_set(int id, char *node, int value);
#define PSU1_AC_HWMON_PREFIX INV_CPLD_PREFIX
#define PSU2_AC_HWMON_PREFIX INV_CPLD_PREFIX
typedef enum psu_type {
PSU_TYPE_UNKNOWN,
@@ -70,6 +66,24 @@ typedef enum psu_type {
psu_type_t get_psu_type(int id, char* modelname, int modelname_len);
#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node
#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node
/*
* Definitions of FAN device
*/
#define FAN_BOARD_PATH INV_PSOC_PREFIX
#define FAN_NODE(node) FAN_BOARD_PATH#node
/*
* Prototypes
*/
int onlp_file_read_binary(char *filename, char *buffer, int buf_size, int data_len);
int onlp_file_read_string(char *filename, char *buffer, int buf_size, int data_len);
int psu_pmbus_info_get(int id, char *node, int *value);
int psu_pmbus_info_set(int id, char *node, int value);
#define DEBUG_MODE 0
#if (DEBUG_MODE == 1)

View File

@@ -1,40 +1,24 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* psui.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/psui.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "platform_lib.h"
#define PSU_STATUS_PRESENT 1
#define PSU_STATUS_POWER_GOOD 1
#define PSU_NODE_MAX_INT_LEN 8
#define PSU_NODE_MAX_PATH_LEN 64
#define PSU_STATUS_PRESENT (0)
#define PSU_STATUS_POWER_GOOD (1)
#define PSU_STATUS_UNPOWERED (2)
#define PSU_STATUS_FAULT (4)
#define PSU_STATUS_UNINSTALLED (7)
#define VALIDATE(_id) \
do { \
@@ -43,55 +27,50 @@
} \
} while(0)
static char* status_devfiles__[CHASSIS_PSU_COUNT+1] = /* must map with onlp_psu_id */
{
"reserved",
INV_CPLD_PREFIX"/psu0",
INV_CPLD_PREFIX"/psu1",
};
static char* module_devfiles__[CHASSIS_PSU_COUNT+1] = /* must map with onlp_psu_id */
{
"reserved",
INV_PSOC_PREFIX"/psoc_psu1_%s",
INV_PSOC_PREFIX"/psoc_psu2_%s",
};
static int
psu_status_info_get(int id, char *node, int *value)
{
int ret = 0;
char node_path[PSU_NODE_MAX_PATH_LEN] = {0};
char node_path[ONLP_NODE_MAX_PATH_LEN] = {0};
char vstr[32], *vstrp = vstr, **vp = &vstrp;
*value = 0;
if (PSU1_ID == id) {
sprintf(node_path, "%s%s", PSU1_AC_HWMON_PREFIX, node);
sprintf(node_path, status_devfiles__[id]);
}
else if (PSU2_ID == id) {
sprintf(node_path, "%s%s", PSU2_AC_HWMON_PREFIX, node);
sprintf(node_path, status_devfiles__[id]);
}
ret = onlp_file_read_int(value, node_path);
ret = onlp_file_read_str(vp, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
return ret;
if (!isdigit(*vstrp)) {
return ONLP_STATUS_E_INTERNAL;
}
*value = *vstrp - '0';
return ONLP_STATUS_OK;
}
static int
psu_ym2651_pmbus_info_get(int id, char *node, int *value)
{
int ret = 0;
char node_path[PSU_NODE_MAX_PATH_LEN] = {0};
*value = 0;
if (PSU1_ID == id) {
sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, node);
}
else {
sprintf(node_path, "%s%s", PSU2_AC_PMBUS_PREFIX, node);
}
ret = onlp_file_read_int(value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
return ret;
}
int
onlp_psui_init(void)
@@ -100,84 +79,73 @@ onlp_psui_init(void)
}
static int
psu_ym2651_info_get(onlp_psu_info_t* info)
psu_module_info_get(int id, onlp_psu_info_t* info)
{
int val = 0;
int index = ONLP_OID_ID_GET(info->hdr.id);
int ret = 0;
char node_path[ONLP_NODE_MAX_PATH_LEN] = {0};
int value = 0;
if (info->status & ONLP_PSU_STATUS_FAILED) {
return ONLP_STATUS_OK;
info->caps |= ONLP_PSU_CAPS_DC12;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "vout");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mvout = value;
info->caps |= ONLP_PSU_CAPS_VOUT;
/* Set the associated oid_table */
info->hdr.coids[0] = ONLP_FAN_ID_CREATE(index + CHASSIS_FAN_COUNT);
info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(index + CHASSIS_THERMAL_COUNT);
/* Read voltage, current and power */
if (psu_ym2651_pmbus_info_get(index, "psu_v_out", &val) == 0) {
info->mvout = val;
info->caps |= ONLP_PSU_CAPS_VOUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "iout");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->miout = value;
info->caps |= ONLP_PSU_CAPS_IOUT;
if (psu_ym2651_pmbus_info_get(index, "psu_i_out", &val) == 0) {
info->miout = val;
info->caps |= ONLP_PSU_CAPS_IOUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "pout");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mpout = value;
info->caps |= ONLP_PSU_CAPS_POUT;
if (psu_ym2651_pmbus_info_get(index, "psu_p_out", &val) == 0) {
info->mpout = val;
info->caps |= ONLP_PSU_CAPS_POUT;
}
return ONLP_STATUS_OK;
}
#include <onlplib/i2c.h>
#define DC12V_750_REG_TO_CURRENT(low, high) (((low << 4 | high >> 4) * 20 * 1000) / 754)
#define DC12V_750_REG_TO_VOLTAGE(low, high) ((low << 4 | high >> 4) * 25)
static int
psu_dc12v_750_info_get(onlp_psu_info_t* info)
{
int pid = ONLP_OID_ID_GET(info->hdr.id);
int bus = (PSU1_ID == pid) ? 11 : 10;
int iout_low, iout_high;
int vout_low, vout_high;
/* Set capability
*/
info->caps = ONLP_PSU_CAPS_DC12;
if (info->status & ONLP_PSU_STATUS_FAILED) {
return ONLP_STATUS_OK;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "vin");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mvin = value;
info->caps |= ONLP_PSU_CAPS_VIN;
/* Get current
*/
iout_low = onlp_i2c_readb(bus, 0x6f, 0x0, ONLP_I2C_F_FORCE);
iout_high = onlp_i2c_readb(bus, 0x6f, 0x1, ONLP_I2C_F_FORCE);
if ((iout_low >= 0) && (iout_high >= 0)) {
info->miout = DC12V_750_REG_TO_CURRENT(iout_low, iout_high);
info->caps |= ONLP_PSU_CAPS_IOUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "iin");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->miin = value;
info->caps |= ONLP_PSU_CAPS_IIN;
/* Get voltage
*/
vout_low = onlp_i2c_readb(bus, 0x6f, 0x2, ONLP_I2C_F_FORCE);
vout_high = onlp_i2c_readb(bus, 0x6f, 0x3, ONLP_I2C_F_FORCE);
if ((vout_low >= 0) && (vout_high >= 0)) {
info->mvout = DC12V_750_REG_TO_VOLTAGE(vout_low, vout_high);
info->caps |= ONLP_PSU_CAPS_VOUT;
}
/* Get power based on current and voltage
*/
if ((info->caps & ONLP_PSU_CAPS_IOUT) && (info->caps & ONLP_PSU_CAPS_VOUT)) {
info->mpout = (info->miout * info->mvout) / 1000;
info->caps |= ONLP_PSU_CAPS_POUT;
memset(node_path, 0, ONLP_NODE_MAX_PATH_LEN);
sprintf(node_path, module_devfiles__[id], "pin");
ret = onlp_file_read_int(&value, node_path);
if (ret < 0) {
AIM_LOG_ERROR("Unable to read status from file(%s)\r\n", node_path);
return ONLP_STATUS_E_INTERNAL;
}
info->mpin = value;
info->caps |= ONLP_PSU_CAPS_PIN;
return ONLP_STATUS_OK;
}
@@ -202,7 +170,6 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
int val = 0;
int ret = ONLP_STATUS_OK;
int index = ONLP_OID_ID_GET(id);
psu_type_t psu_type;
VALIDATE(id);
@@ -210,63 +177,27 @@ onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
*info = pinfo[index]; /* Set the onlp_oid_hdr_t */
/* Get the present state */
if (psu_status_info_get(index, "psu_present", &val) != 0) {
if ((ret = psu_status_info_get(index, "psu", &val)) == ONLP_STATUS_E_INTERNAL) {
printf("Unable to read PSU(%d) node(psu_present)\r\n", index);
return ret;
}
if (val != PSU_STATUS_PRESENT) {
info->status &= ~ONLP_PSU_STATUS_PRESENT;
return ONLP_STATUS_OK;
if (val == 0) {
info->status = ONLP_PSU_STATUS_PRESENT;
}
info->status |= ONLP_PSU_STATUS_PRESENT;
/* Get power good status */
if (psu_status_info_get(index, "psu_power_good", &val) != 0) {
printf("Unable to read PSU(%d) node(psu_power_good)\r\n", index);
else
if (val == 1) {
info->status = ONLP_PSU_STATUS_UNPLUGGED;
return ret;
}
else {
info->status = ONLP_PSU_STATUS_FAILED;
return ret;
}
if (val != PSU_STATUS_POWER_GOOD) {
info->status |= ONLP_PSU_STATUS_FAILED;
}
/* Get PSU type
*/
psu_type = get_psu_type(index, info->model, sizeof(info->model));
switch (psu_type) {
case PSU_TYPE_AC_F2B:
case PSU_TYPE_AC_B2F:
info->caps = ONLP_PSU_CAPS_AC;
ret = psu_ym2651_info_get(info);
break;
case PSU_TYPE_DC_48V_F2B:
case PSU_TYPE_DC_48V_B2F:
info->caps = ONLP_PSU_CAPS_DC48;
ret = psu_ym2651_info_get(info);
break;
case PSU_TYPE_DC_12V_F2B:
case PSU_TYPE_DC_12V_B2F:
case PSU_TYPE_DC_12V_FANLESS:
ret = psu_dc12v_750_info_get(info);
break;
case PSU_TYPE_UNKNOWN: /* User insert a unknown PSU or unplugged.*/
info->status |= ONLP_PSU_STATUS_UNPLUGGED;
info->status &= ~ONLP_PSU_STATUS_FAILED;
ret = ONLP_STATUS_OK;
break;
default:
ret = ONLP_STATUS_E_UNSUPPORTED;
break;
if ((ret = psu_module_info_get(index, info)) != ONLP_STATUS_OK) {
printf("Unable to read PSU(%d) module information\r\n", index);
}
return ret;
}
int
onlp_psui_ioctl(onlp_oid_t pid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -1,27 +1,10 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* sfpi.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <onlp/platformi/sfpi.h>
@@ -34,19 +17,40 @@
#include <onlplib/file.h>
#include "platform_lib.h"
#define MAX_SFP_PATH 64
static char sfp_node_path[MAX_SFP_PATH] = {0};
static char sfp_node_path[ONLP_NODE_MAX_PATH_LEN] = {0};
#define MUX_START_INDEX 18
#define NUM_OF_SFP_PORT 32
#define NUM_OF_SFP_PORT (CHASSIS_SFP_COUNT)
static const int sfp_mux_index[NUM_OF_SFP_PORT] = {
4, 5, 6, 7, 9, 8, 11, 10,
0, 1, 2, 3, 12, 13, 14, 15,
16, 17, 18, 19, 28, 29, 30, 31,
20, 21, 22, 23, 24, 25, 26, 27
#ifdef SWPS_CYPRESS_GA1
10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63
#endif
#ifdef SWPS_CYPRESS_GA2
11, 10, 13, 12, 15, 14, 17, 16,
19, 18, 21, 20, 23, 22, 25, 24,
27, 26, 29, 28, 31, 30, 33, 32,
35, 34, 37, 36, 39, 38, 41, 40,
43, 42, 45, 44, 47, 46, 49, 48,
51, 50, 53, 52, 55, 54, 57, 56,
59, 58, 61, 60, 63, 62
#endif
#ifdef SWPS_CYPRESS_BAI
11, 10, 13, 12, 15, 14, 17, 16,
19, 18, 21, 20, 23, 22, 25, 24,
27, 26, 29, 28, 31, 30, 33, 32,
35, 34, 37, 36, 39, 38, 41, 40,
43, 42, 45, 44, 47, 46, 49, 48,
51, 50, 53, 52, 55, 54, 57, 56,
59, 58, 61, 60, 63, 62
#endif
};
#define FRONT_PORT_TO_MUX_INDEX(port) (sfp_mux_index[port]+MUX_START_INDEX)
#define FRONT_PORT_TO_MUX_INDEX(port) (sfp_mux_index[port])
static int
sfp_node_read_int(char *node_path, int *value, int data_len)
@@ -67,9 +71,7 @@ sfp_node_read_int(char *node_path, int *value, int data_len)
static char*
sfp_get_port_path(int port, char *node_name)
{
sprintf(sfp_node_path, "/sys/bus/i2c/devices/%d-0050/%s",
FRONT_PORT_TO_MUX_INDEX(port),
node_name);
sprintf(sfp_node_path, "/sys/class/swps/port%d/%s", port, node_name);
return sfp_node_path;
}
@@ -90,7 +92,7 @@ int
onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap)
{
/*
* Ports {0, 32}
* Ports {0, 54}
*/
int p;
AIM_BITMAP_CLR_ALL(bmap);
@@ -111,66 +113,65 @@ onlp_sfpi_is_present(int port)
* Return < 0 if error.
*/
int present;
char* path = sfp_get_port_path(port, "sfp_is_present");
char* path = sfp_get_port_path(port, "present");
if (sfp_node_read_int(path, &present, 0) != 0) {
AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
if (present == 0) {
present = 1;
}
else
if (present == 1) {
present = 0;
}
else {
AIM_LOG_ERROR("Unvalid present status %d from port(%d)\r\n",present,port);
return ONLP_STATUS_E_INTERNAL;
}
return present;
}
int
onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
{
uint32_t bytes[4];
char* path;
FILE* fp;
uint32_t presence_all[2] = {0};
int port, ret, index;
path = sfp_get_port_path(0, "sfp_is_present_all");
fp = fopen(path, "r");
for (port = 0, index = 0; port < NUM_OF_SFP_PORT; port++) {
if (port == 32) {
index = 1;
}
if(fp == NULL) {
AIM_LOG_ERROR("Unable to open the sfp_is_present_all device file.");
return ONLP_STATUS_E_INTERNAL;
ret = onlp_sfpi_is_present(port);
if (ret == 1) {
presence_all[index] |= (1<<port);
}
else
if (ret == 0) {
presence_all[index] &= ~(1<<port);
}
else {
AIM_LOG_ERROR("Unable to read present status of port(%d).", port);
}
}
int count = fscanf(fp, "%x %x %x %x",
bytes+0,
bytes+1,
bytes+2,
bytes+3
);
fclose(fp);
if(count != AIM_ARRAYSIZE(bytes)) {
/* Likely a CPLD read timeout. */
AIM_LOG_ERROR("Unable to read all fields from the sfp_is_present_all device file.");
return ONLP_STATUS_E_INTERNAL;
}
/* Convert to 64 bit integer in port order */
int i = 0;
uint32_t presence_all = 0 ;
for(i = AIM_ARRAYSIZE(bytes)-1; i >= 0; i--) {
presence_all <<= 8;
presence_all |= bytes[i];
}
/* Populate bitmap */
for(i = 0; presence_all; i++) {
AIM_BITMAP_MOD(dst, i, (presence_all & 1));
presence_all >>= 1;
}
for(port = 0, index = 0; port < NUM_OF_SFP_PORT; port++) {
if (port == 32) {
index = 1;
}
AIM_BITMAP_MOD(dst, port, (presence_all[index] & 1));
presence_all[index] >>= 1;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
char* path = sfp_get_port_path(port, "sfp_eeprom");
char* path;
int len = 0;
/*
* Read the SFP eeprom into data[]
*
@@ -178,15 +179,20 @@ onlp_sfpi_eeprom_read(int port, uint8_t data[256])
* Return OK if eeprom is read
*/
memset(data, 0, 256);
if (onlp_file_read((uint8_t*)data, 256, &len, path) < 0) {
path = sfp_get_port_path(port, "eeprom");
if (onlp_file_read(&data[0], 256, &len, path) < 0) {
AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_dom_read(int port, uint8_t data[256])
{
return onlp_sfpi_eeprom_read( port, data);
}
int
onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr)
{

View File

@@ -1,27 +1,10 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* sysi.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <unistd.h>
#include <fcntl.h>
@@ -38,19 +21,12 @@
#include "platform_lib.h"
#define NUM_OF_THERMAL_ON_MAIN_BROAD CHASSIS_THERMAL_COUNT
#define NUM_OF_FAN_ON_MAIN_BROAD CHASSIS_FAN_COUNT
#define NUM_OF_PSU_ON_MAIN_BROAD 2
#define NUM_OF_LED_ON_MAIN_BROAD 5
#define NUM_OF_CPLD INV_CPLD_COUNT
#define PREFIX_PATH_ON_CPLD_DEV "/sys/bus/i2c/devices/"
#define NUM_OF_CPLD 3
static char arr_cplddev_name[NUM_OF_CPLD][10] =
{
"4-0060",
"5-0062",
"6-0064"
};
#define NUM_OF_THERMAL_ON_MAIN_BROAD (CHASSIS_THERMAL_COUNT)
#define NUM_OF_FAN_ON_MAIN_BROAD (CHASSIS_FAN_COUNT)
#define NUM_OF_PSU_ON_MAIN_BROAD (CHASSIS_PSU_COUNT)
#define NUM_OF_LED_ON_MAIN_BROAD (CHASSIS_LED_COUNT)
const char*
onlp_sysi_platform_get(void)
@@ -62,7 +38,7 @@ int
onlp_sysi_onie_data_get(uint8_t** data, int* size)
{
uint8_t* rdata = aim_zmalloc(256);
if(onlp_file_read(rdata, 256, size, IDPROM_PATH) == ONLP_STATUS_OK) {
if(onlp_file_read(rdata, 256, size, EEPROM_NODE(eeprom)) == ONLP_STATUS_OK) {
if(*size == 256) {
*data = rdata;
return ONLP_STATUS_OK;
@@ -74,27 +50,6 @@ onlp_sysi_onie_data_get(uint8_t** data, int* size)
return ONLP_STATUS_E_INTERNAL;
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
int i, v[NUM_OF_CPLD]={0};
for (i=0; i < NUM_OF_CPLD; i++) {
v[i] = 0;
if(onlp_file_read_int(v+i, "%s%s/version", PREFIX_PATH_ON_CPLD_DEV, arr_cplddev_name[i]) < 0) {
return ONLP_STATUS_E_INTERNAL;
}
}
pi->cpld_versions = aim_fstrdup("%d.%d.%d", v[0], v[1], v[2]);
return 0;
}
void
onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
{
aim_free(pi->cpld_versions);
}
int
onlp_sysi_oids_get(onlp_oid_t* table, int max)
{
@@ -129,167 +84,27 @@ onlp_sysi_oids_get(onlp_oid_t* table, int max)
return 0;
}
typedef struct fan_ctrl_policy {
int duty_cycle;
int temp_down_adjust; /* The boundary temperature to down adjust fan speed */
int temp_up_adjust; /* The boundary temperature to up adjust fan speed */
} fan_ctrl_policy_t;
fan_ctrl_policy_t fan_ctrl_policy_f2b[] = {
{32, 0, 174000},
{38, 170000, 182000},
{50, 178000, 190000},
{63, 186000, 0}
};
fan_ctrl_policy_t fan_ctrl_policy_b2f[] = {
{32, 0, 140000},
{38, 135000, 150000},
{50, 145000, 160000},
{69, 155000, 0}
};
#define FAN_DUTY_CYCLE_MAX 100
#define FAN_SPEED_CTRL_PATH "/sys/bus/i2c/devices/2-0066/fan_duty_cycle_percentage"
/*
* For AC power Front to Back :
* * If any fan fail, please fan speed register to 15
* * The max value of Fan speed register is 9
* [LM75(48) + LM75(49) + LM75(4A)] > 174 => set Fan speed value from 4 to 5
* [LM75(48) + LM75(49) + LM75(4A)] > 182 => set Fan speed value from 5 to 7
* [LM75(48) + LM75(49) + LM75(4A)] > 190 => set Fan speed value from 7 to 9
*
* [LM75(48) + LM75(49) + LM75(4A)] < 170 => set Fan speed value from 5 to 4
* [LM75(48) + LM75(49) + LM75(4A)] < 178 => set Fan speed value from 7 to 5
* [LM75(48) + LM75(49) + LM75(4A)] < 186 => set Fan speed value from 9 to 7
*
*
* For AC power Back to Front :
* * If any fan fail, please fan speed register to 15
* * The max value of Fan speed register is 10
* [LM75(48) + LM75(49) + LM75(4A)] > 140 => set Fan speed value from 4 to 5
* [LM75(48) + LM75(49) + LM75(4A)] > 150 => set Fan speed value from 5 to 7
* [LM75(48) + LM75(49) + LM75(4A)] > 160 => set Fan speed value from 7 to 10
*
* [LM75(48) + LM75(49) + LM75(4A)] < 135 => set Fan speed value from 5 to 4
* [LM75(48) + LM75(49) + LM75(4A)] < 145 => set Fan speed value from 7 to 5
* [LM75(48) + LM75(49) + LM75(4A)] < 155 => set Fan speed value from 10 to 7
*/
int
onlp_sysi_platform_manage_fans(void)
static char *arr_cplddev_version[NUM_OF_CPLD] =
{
int i = 0, arr_size, temp;
fan_ctrl_policy_t *policy;
int cur_duty_cycle, new_duty_cycle;
onlp_thermal_info_t thermal_1, thermal_2, thermal_3;
INV_CPLD_PREFIX"/version",
};
int fd, len;
char buf[10] = {0};
/* Get each fan status
*/
for (i = 1; i <= NUM_OF_FAN_ON_MAIN_BROAD; i++)
{
onlp_fan_info_t fan_info;
if (onlp_fan_info_get(ONLP_FAN_ID_CREATE(i), &fan_info) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to get fan(%d) status\r\n", i);
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
int i, v[NUM_OF_CPLD]={0};
for (i=0; i < NUM_OF_CPLD; i++) {
v[i] = 0;
if(onlp_file_read_int(v+i, arr_cplddev_version[i]) < 0) {
return ONLP_STATUS_E_INTERNAL;
}
/* Decision 1: Set fan as full speed if any fan is failed.
*/
if (fan_info.status & ONLP_FAN_STATUS_FAILED) {
AIM_LOG_ERROR("Fan(%d) is not working, set the other fans as full speed\r\n", i);
return onlp_fan_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
/* Decision 1.1: Set fan as full speed if any fan is not present.
*/
if (!(fan_info.status & ONLP_FAN_STATUS_PRESENT)) {
AIM_LOG_ERROR("Fan(%d) is not present, set the other fans as full speed\r\n", i);
return onlp_fan_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
/* Get fan direction (Only get the first one since all fan direction are the same)
*/
if (i == 1) {
if (fan_info.status & ONLP_FAN_STATUS_F2B) {
policy = fan_ctrl_policy_f2b;
arr_size = AIM_ARRAYSIZE(fan_ctrl_policy_f2b);
}
else {
policy = fan_ctrl_policy_b2f;
arr_size = AIM_ARRAYSIZE(fan_ctrl_policy_b2f);
}
}
}
/* Get current fan speed
*/
fd = open(FAN_SPEED_CTRL_PATH, O_RDONLY);
if (fd == -1){
AIM_LOG_ERROR("Unable to open fan speed control node (%s)", FAN_SPEED_CTRL_PATH);
return ONLP_STATUS_E_INTERNAL;
}
len = read(fd, buf, sizeof(buf));
close(fd);
if (len <= 0) {
AIM_LOG_ERROR("Unable to read fan speed from (%s)", FAN_SPEED_CTRL_PATH);
return ONLP_STATUS_E_INTERNAL;
}
cur_duty_cycle = atoi(buf);
/* Decision 2: If no matched fan speed is found from the policy,
* use FAN_DUTY_CYCLE_MIN as default speed
*/
for (i = 0; i < arr_size; i++) {
if (policy[i].duty_cycle != cur_duty_cycle)
continue;
break;
}
if (i == arr_size) {
return onlp_fan_percentage_set(ONLP_FAN_ID_CREATE(1), policy[0].duty_cycle);
}
/* Get current temperature
*/
if (onlp_thermal_info_get(ONLP_THERMAL_ID_CREATE(2), &thermal_1) != ONLP_STATUS_OK ||
onlp_thermal_info_get(ONLP_THERMAL_ID_CREATE(3), &thermal_2) != ONLP_STATUS_OK ||
onlp_thermal_info_get(ONLP_THERMAL_ID_CREATE(4), &thermal_3) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to read thermal status");
return ONLP_STATUS_E_INTERNAL;
}
temp = thermal_1.mcelsius + thermal_2.mcelsius + thermal_3.mcelsius;
/* Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature
*/
new_duty_cycle = cur_duty_cycle;
if ((temp >= policy[i].temp_up_adjust) && (i != (arr_size-1))) {
new_duty_cycle = policy[i+1].duty_cycle;
}
else if ((temp <= policy[i].temp_down_adjust) && (i != 0)) {
new_duty_cycle = policy[i-1].duty_cycle;
}
if (new_duty_cycle == cur_duty_cycle) {
/* Duty cycle does not change, just return */
return ONLP_STATUS_OK;
}
return onlp_fan_percentage_set(ONLP_FAN_ID_CREATE(1), new_duty_cycle);
pi->cpld_versions = aim_fstrdup("%d.%d", v[0], v[1]);
return 0;
}
int
onlp_sysi_platform_manage_leds(void)
void
onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
{
return ONLP_STATUS_E_UNSUPPORTED;
aim_free(pi->cpld_versions);
}

View File

@@ -1,23 +1,8 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
* thermali.c
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright 2014 Accton Technology Corporation.
* Copyright 2018 Inventec Technology Corporation.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Thermal Sensor Platform Implementation.
@@ -40,39 +25,61 @@
enum onlp_thermal_id
{
THERMAL_RESERVED = 0,
THERMAL_CPU_CORE,
THERMAL_CPU_CORE_FIRST,
THERMAL_CPU_CORE_2,
THERMAL_CPU_CORE_3,
THERMAL_CPU_CORE_4,
THERMAL_CPU_CORE_LAST,
THERMAL_1_ON_MAIN_BROAD,
THERMAL_2_ON_MAIN_BROAD,
THERMAL_3_ON_MAIN_BROAD,
THERMAL_4_ON_MAIN_BROAD,
THERMAL_5_ON_MAIN_BROAD,
THERMAL_1_ON_PSU1,
THERMAL_1_ON_PSU2,
THERMAL_2_ON_PSU1,
THERMAL_2_ON_PSU2,
};
static char* devfiles__[] = /* must map with onlp_thermal_id */
static char* devfiles__[CHASSIS_THERMAL_COUNT+1] = /* must map with onlp_thermal_id */
{
"reserved",
NULL, /* CPU_CORE files */
"/sys/bus/i2c/devices/3-0048*temp1_input",
"/sys/bus/i2c/devices/3-0049*temp1_input",
"/sys/bus/i2c/devices/3-004a*temp1_input",
"/sys/bus/i2c/devices/3-004b*temp1_input",
"/sys/bus/i2c/devices/11-005b*psu_temp1_input",
"/sys/bus/i2c/devices/10-0058*psu_temp1_input",
INV_CTMP_PREFIX"/temp1_%s",
INV_CTMP_PREFIX"/temp2_%s",
INV_CTMP_PREFIX"/temp3_%s",
INV_CTMP_PREFIX"/temp4_%s",
INV_CTMP_PREFIX"/temp5_%s",
INV_PSOC_PREFIX"/temp1_input",
INV_PSOC_PREFIX"/temp2_input",
INV_PSOC_PREFIX"/temp3_input",
INV_PSOC_PREFIX"/temp4_input",
INV_PSOC_PREFIX"/temp5_input",
INV_PSOC_PREFIX"/thermal_psu1",
INV_PSOC_PREFIX"/thermal_psu2",
INV_PSOC_PREFIX"/thermal2_psu1",
INV_PSOC_PREFIX"/thermal2_psu2",
};
static char* cpu_coretemp_files[] =
{
"/sys/devices/platform/coretemp.0*temp2_input",
"/sys/devices/platform/coretemp.0*temp3_input",
"/sys/devices/platform/coretemp.0*temp4_input",
"/sys/devices/platform/coretemp.0*temp5_input",
NULL,
};
/* Static values */
static onlp_thermal_info_t linfo[] = {
static onlp_thermal_info_t linfo[CHASSIS_THERMAL_COUNT+1] = {
{ }, /* Not used */
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE), "CPU Core", 0},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_FIRST), "Physical id 0", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_2), "CPU Core 0", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_3), "CPU Core 1", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_4), "CPU Core 2", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_LAST), "CPU Core 3", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
@@ -92,6 +99,10 @@ static onlp_thermal_info_t linfo[] = {
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BROAD), "Chassis Thermal Sensor 5", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU1), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU1_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
@@ -99,6 +110,14 @@ static onlp_thermal_info_t linfo[] = {
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_PSU2), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU2_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_PSU1), "PSU-1 Thermal Sensor 2", ONLP_PSU_ID_CREATE(PSU1_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_PSU2), "PSU-2 Thermal Sensor 2", ONLP_PSU_ID_CREATE(PSU2_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
}
};
@@ -132,10 +151,16 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[local_id];
if(local_id == THERMAL_CPU_CORE) {
int rv = onlp_file_read_int_max(&info->mcelsius, cpu_coretemp_files);
return rv;
}
if(local_id >= THERMAL_CPU_CORE_FIRST && local_id <= THERMAL_CPU_CORE_LAST) {
char desc[32], *dp = &desc[0];
int rv = onlp_file_read_str(&dp, devfiles__[local_id], "label");
if (rv > 0) {
memset (info->hdr.description, 0, ONLP_OID_DESC_SIZE);
strncpy(info->hdr.description, dp, rv);
}
/* Set the onlp_oid_hdr_t and capabilities */
return onlp_file_read_int(&info->mcelsius, devfiles__[local_id], "input");
}
return onlp_file_read_int(&info->mcelsius, devfiles__[local_id]);
}

View File

@@ -2,14 +2,19 @@ from onl.platform.base import *
from onl.platform.inventec import *
class OnlPlatform_x86_64_inventec_d7054q28b_r0(OnlPlatformInventec,
OnlPlatformPortConfig_32x100):
OnlPlatformPortConfig_48x25_6x100):
PLATFORM='x86-64-inventec-d7054q28b-r0'
MODEL="X86-D7054Q28B"
SYS_OBJECT_ID="7054.28"
def baseconfig(self):
os.system("insmod /lib/modules/`uname -r`/kernel/drivers/gpio/gpio-ich.ko gpiobase=0")
os.system("insmod /lib/modules/`uname -r`/kernel/drivers/gpio/gpio-ich.ko")
self.insmod('inv_platform')
self.insmod('inv_psoc')
self.insmod('inv_cpld')
self.new_i2c_device('inv_eeprom', 0x53, 0)
self.insmod('inv_eeprom')
self.insmod('swps')
self.insmod('vpd')
self.insmod('inv_pthread')
return True