Merge branch 'master' of github.com:opencomputeproject/OpenNetworkLinux

This commit is contained in:
Jeffrey Townsend
2017-04-14 18:35:10 +00:00
163 changed files with 11432 additions and 86 deletions

View File

@@ -105,29 +105,10 @@ Adding/Removing packages from a SWI:
The list of packages for a given SWI are in
$ONL/packages/base/any/rootfs/$suite/common/$ARCH-packages.yml # for $ARCH specific packages
$ONL/packages/base/any/rootfs/$suite/common/common-packages.yml # for $ARCH-independent packages
$ONL/builds/any/rootfs/jessie/common/*.yml
Build a software image (SWI) for all powerpc platforms:
------------------------------------------------------------
#> cd $ONL/builds/powerpc/swi
#> make
#> cd builds
#> ls *.swi
ONL-2.0.0_ONL-OS_2015-12-12.0252-ffce159_PPC.swi
#>
The "all-base-packages.yml" file is for all architectures and the rest are architecture specific package lists.
Build an ONIE-compatible installer for all powerpc platforms.
This will incorporate the SWI you just built or build it dynamically if not.
This installer image can be served to ONIE on Quanta or Accton platforms:
------------------------------------------------------------
#> cd $ONL/builds/powerpc/installer/legacy
#> make
#> cd builds
#> ls *INSTALLER
ONL-2.0.0_ONL-OS_2015-12-12.0252-ffce159_PPC_INSTALLER
#>
Example setup on new Debian 8.2 installation
------------------------------------------------------------

View File

@@ -85,9 +85,10 @@ case "${NETAUTO}" in
if [ "${NETIP}" ] && [ "${NETMASK}" ] && [ "${NETIP#*/}" = "${NETIP}" ]; then
NETIP=${NETIP}/$(ipcalc -p -s ${NETIP} ${NETMASK} | sed -n 's/PREFIX=//p')
fi
ip link set ${NETDEV} down
echo 0 >/proc/sys/net/ipv6/conf/${NETDEV}/autoconf
ip addr flush dev ${NETDEV}
ip addr flush dev ${NETDEV}
ip route flush dev ${NETDEV}
if [ "${NETIP}" ]; then
ip addr add ${NETIP} dev ${NETDEV}
fi

View File

@@ -106,7 +106,10 @@ class SubprocessMixin:
sys.stderr.write(fd.read())
os.unlink(v2Out)
else:
return subprocess.check_output(cmd, *args, cwd=cwd, **kwargs)
try:
return subprocess.check_output(cmd, *args, cwd=cwd, **kwargs)
except subprocess.CalledProcessError:
return ''
def rmdir(self, path):
self.log.debug("+ /bin/rmdir %s", path)

View File

@@ -506,3 +506,7 @@ class OnlPlatformPortConfig_24x1_4x10(object):
class OnlPlatformPortConfig_8x1_8x10(object):
PORT_COUNT=16
PORT_CONFIG="8x1 + 8x10"
class OnlPlatformPortConfig_48x10_6x100(object):
PORT_COUNT=54
PORT_CONFIG="48x10 + 6x100"

View File

@@ -507,6 +507,7 @@ CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
# CONFIG_ACPI_IPMI is not set
CONFIG_ACPI_HOTPLUG_CPU=y
# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
CONFIG_ACPI_THERMAL=y
@@ -1823,7 +1824,13 @@ CONFIG_SERIAL_JSM=y
# CONFIG_TTY_PRINTK is not set
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_IPMI_HANDLER is not set
CONFIG_IPMI_HANDLER=y
# CONFIG_IPMI_PANIC_EVENT is not set
CONFIG_IPMI_DEVICE_INTERFACE=y
CONFIG_IPMI_SI=y
CONFIG_IPMI_SI_PROBE_DEFAULTS=y
CONFIG_IPMI_WATCHDOG=y
CONFIG_IPMI_POWEROFF=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=y
CONFIG_HW_RANDOM_INTEL=y
@@ -2101,6 +2108,8 @@ CONFIG_SENSORS_ADM1021=y
# CONFIG_SENSORS_G762 is not set
CONFIG_SENSORS_GPIO_FAN=y
# CONFIG_SENSORS_HIH6130 is not set
# CONFIG_SENSORS_IBMAEM is not set
# CONFIG_SENSORS_IBMPEX is not set
CONFIG_SENSORS_CORETEMP=y
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_JC42 is not set
@@ -2182,7 +2191,7 @@ CONFIG_SENSORS_UCD9200=y
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP102 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
CONFIG_SENSORS_TMP421=y
# CONFIG_SENSORS_VIA_CPUTEMP is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set

View File

@@ -0,0 +1,96 @@
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index d65a0b1..e070d26 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -104,6 +104,7 @@ static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl);
static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data);
static bool e1000_get_i2c_data(u32 *i2cctl);
+static s32 e1000_set_phy_mode_external_50210(struct e1000_hw *hw, struct e1000_phy_info *phy, u32 ctrl_ext);
static const u16 e1000_82580_rxpbs_table[] = {
36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
@@ -215,6 +216,11 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
/* Set phy->phy_addr and phy->id. */
ret_val = e1000_get_phy_id_82575(hw);
+ if(phy->id == NULL)
+ {
+ ret_val = e1000_set_phy_mode_external_50210(hw, phy, ctrl_ext);
+ }
+
/* Verify phy id and set remaining function pointers */
switch (phy->id) {
case M88E1543_E_PHY_ID:
@@ -312,6 +318,8 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
case BCM54616_E_PHY_ID:
phy->type = e1000_phy_bcm54616;
break;
+ case BCM50210S_E_PHY_ID:
+ break;
default:
ret_val = -E1000_ERR_PHY;
goto out;
@@ -3934,3 +3942,47 @@ s32 e1000_init_thermal_sensor_thresh_generic(struct e1000_hw *hw)
}
return E1000_SUCCESS;
}
+
+static s32 e1000_set_phy_mode_external_50210(struct e1000_hw *hw, struct e1000_phy_info *phy, u32 ctrl_ext)
+{
+ u32 u32Data = 0;
+ s32 ret_val = E1000_SUCCESS;
+
+ u32Data = E1000_READ_REG(hw, E1000_MDICNFG);
+ u32Data |= 0x80000000;
+ E1000_WRITE_REG(hw, E1000_MDICNFG, u32Data);
+
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+ e1000_reset_mdicnfg_82580(hw);
+
+ if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw))
+ {
+ phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
+ phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
+ }
+ else
+ {
+ switch (hw->mac.type)
+ {
+ case e1000_82580:
+ case e1000_i350:
+ case e1000_i354:
+ phy->ops.read_reg = e1000_read_phy_reg_82580;
+ phy->ops.write_reg = e1000_write_phy_reg_82580;
+ break;
+ case e1000_i210:
+ case e1000_i211:
+ phy->ops.read_reg = e1000_read_phy_reg_gs40g;
+ phy->ops.write_reg = e1000_write_phy_reg_gs40g;
+ break;
+ default:
+ phy->ops.read_reg = e1000_read_phy_reg_igp;
+ phy->ops.write_reg = e1000_write_phy_reg_igp;
+ }
+ }
+
+ /* Set phy->phy_addr and phy->id. */
+ ret_val = e1000_get_phy_id_82575(hw);
+
+ return ret_val;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index c21f0be..29d8933 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -1186,7 +1186,8 @@
#define IGP04E1000_E_PHY_ID 0x02A80391
#define BCM54616_E_PHY_ID 0x3625D10
#define BCM5461S_PHY_ID 0x002060C0
-#define M88_VENDOR 0x0141
+#define M88_VENDOR 0x0141
+#define BCM50210S_E_PHY_ID 0x600d8590
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Reg */

View File

@@ -24,3 +24,4 @@ drivers-net-ethernet-broadcom-tg3-preamble-reset.patch
platform-powerpc-85xx-Makefile.patch
platform-powerpc-dni-7448-r0.patch
platform-powerpc-quanta-lb9-r0.patch
driver-support-intel-igb-bcm50210-phy.patch

View File

@@ -38,7 +38,7 @@ struct cpld_client_node {
/* Addresses scanned for accton_i2c_cpld
*/
static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, I2C_CLIENT_END };
static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, 0x64, I2C_CLIENT_END };
static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf)
{

View File

@@ -82,6 +82,10 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
struct as7512_32x_psu_data *data = as7512_32x_psu_update_device(dev);
u8 status = 0;
if (!data->valid) {
return -EIO;
}
if (attr->index == PSU_PRESENT) {
status = !(data->status >> ((2 - data->index) + 2) & 0x1);
}
@@ -230,6 +234,7 @@ static struct as7512_32x_psu_data *as7512_32x_psu_update_device(struct device *d
int status;
int power_good = 0;
data->valid = 0;
dev_dbg(&client->dev, "Starting as7512_32x update\n");
/* Read psu status */
@@ -237,6 +242,7 @@ static struct as7512_32x_psu_data *as7512_32x_psu_update_device(struct device *d
if (status < 0) {
dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status);
goto exit;
}
else {
data->status = status;
@@ -253,6 +259,7 @@ static struct as7512_32x_psu_data *as7512_32x_psu_update_device(struct device *d
if (status < 0) {
data->model_name[0] = '\0';
dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr);
goto exit;
}
else {
data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0';
@@ -263,6 +270,7 @@ static struct as7512_32x_psu_data *as7512_32x_psu_update_device(struct device *d
data->valid = 1;
}
exit:
mutex_unlock(&data->update_lock);
return data;

View File

@@ -57,7 +57,7 @@ typedef struct fan_path_S
#define _MAKE_FAN_PATH_ON_MAIN_BOARD(prj,id) \
{ #prj"fan"#id"_fault", #prj"fan"#id"_front_speed_rpm", \
#prj"fan"#id"_duty_cycle_percentage", #prj"fan"#id"_rear_speed_rpm" }
#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)
@@ -173,6 +173,7 @@ _onlp_fani_info_get_fan(int local_id, onlp_fan_info_t* info)
OPEN_READ_FILE(fd,fullpath,r_data,nbytes,len);
if (atoi(r_data) > 0) {
info->status |= ONLP_FAN_STATUS_FAILED;
return ONLP_STATUS_OK;
}
/* get fan direction (both : the same)

View File

@@ -66,7 +66,7 @@ int deviceNodeWriteInt(char *filename, int value, int data_len)
char buf[8] = {0};
sprintf(buf, "%d", value);
return deviceNodeWrite(filename, buf, sizeof(buf)-1, data_len);
return deviceNodeWrite(filename, buf, (int)strlen(buf), data_len);
}
int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_len)

View File

@@ -26,6 +26,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <onlplib/file.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/thermali.h>
@@ -34,14 +35,23 @@
#include "x86_64_accton_as7512_32x_int.h"
#include "x86_64_accton_as7512_32x_log.h"
#include "platform_lib.h"
#include <onlplib/file.h>
#define NUM_OF_THERMAL_ON_MAIN_BROAD 5
#define NUM_OF_FAN_ON_MAIN_BROAD 6
#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 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"
};
const char*
onlp_sysi_platform_get(void)
{
@@ -58,11 +68,33 @@ onlp_sysi_onie_data_get(uint8_t** data, int* size)
return ONLP_STATUS_OK;
}
}
aim_free(rdata);
*size = 0;
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)
{

View File

@@ -25,12 +25,11 @@
***********************************************************/
#include <unistd.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include <onlp/platformi/thermali.h>
#include <fcntl.h>
#include "platform_lib.h"
#define prefix_path "/sys/bus/i2c/devices/"
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_THERMAL(_id)) { \
@@ -38,17 +37,6 @@
} \
} while(0)
#define OPEN_READ_FILE(fd,fullpath,data,nbytes,len) \
DEBUG_PRINT("[Debug][%s][%d][openfile: %s]\n", __FUNCTION__, __LINE__, fullpath); \
if ((fd = open(fullpath, O_RDONLY)) == -1) \
return ONLP_STATUS_E_INTERNAL; \
if ((len = read(fd, r_data, nbytes)) <= 0){ \
close(fd); \
return ONLP_STATUS_E_INTERNAL;} \
DEBUG_PRINT("[Debug][%s][%d][read data: %s]\n", __FUNCTION__, __LINE__, r_data); \
if (close(fd) == -1) \
return ONLP_STATUS_E_INTERNAL
enum onlp_thermal_id
{
THERMAL_RESERVED = 0,
@@ -61,16 +49,16 @@ enum onlp_thermal_id
THERMAL_1_ON_PSU2,
};
static char last_path[][30] = /* must map with onlp_thermal_id */
static char* devfiles__[] = /* must map with onlp_thermal_id */
{
"reserved",
"3-0048/temp1_input",
"3-0049/temp1_input",
"3-004a/temp1_input",
"15-004c/temp1_input",
"15-004c/temp2_input",
"10-0058/psu_temp1_input",
"11-005b/psu_temp1_input",
"/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/15-004c*temp1_input",
"/sys/bus/i2c/devices/15-004c*temp2_input",
"/sys/bus/i2c/devices/10-0058*psu_temp1_input",
"/sys/bus/i2c/devices/11-005b*psu_temp1_input",
};
/* Static values */
@@ -128,24 +116,13 @@ onlp_thermali_init(void)
int
onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
{
int fd, len, nbytes = 10, temp_base=1, local_id;
char r_data[10] = {0};
char fullpath[50] = {0};
int local_id;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
DEBUG_PRINT("\n[Debug][%s][%d][local_id: %d]", __FUNCTION__, __LINE__, local_id);
/* get fullpath */
sprintf(fullpath, "%s%s", prefix_path, last_path[local_id]);
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[local_id];
OPEN_READ_FILE(fd, fullpath, r_data, nbytes, len);
info->mcelsius = atoi(r_data) / temp_base;
DEBUG_PRINT("\n[Debug][%s][%d][save data: %d]\n", __FUNCTION__, __LINE__, info->mcelsius);
return ONLP_STATUS_OK;
return onlp_file_read_int(&info->mcelsius, devfiles__[local_id]);
}

View File

@@ -31,9 +31,9 @@ class OnlPlatform_x86_64_accton_as7512_32x_r0(OnlPlatformAccton,
# initialize CPLD
self.new_i2c_devices(
[
('accton_i2c_cpld', 0x60, 0),
('accton_i2c_cpld', 0x62, 0),
('accton_i2c_cpld', 0x64, 0),
('accton_i2c_cpld', 0x60, 4),
('accton_i2c_cpld', 0x62, 5),
('accton_i2c_cpld', 0x64, 6),
]
)
########### initialize I2C bus 1 ###########
@@ -46,11 +46,11 @@ class OnlPlatform_x86_64_accton_as7512_32x_r0(OnlPlatformAccton,
('pca9548', 0x71, 1),
# initiate PSU-1
('as7512_32x_psu1', 0x50, 10),
('as7512_32x_psu', 0x50, 10),
('ym2651', 0x58, 10),
# initiate PSU-2
('as7512_32x_psu2', 0x53, 11),
('as7512_32x_psu', 0x53, 11),
('ym2651', 0x5b, 11),
#initiate max6657 thermal sensor

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-config-vendor.yml VENDOR=delta Vendor=Delta

View File

@@ -0,0 +1,7 @@
#!/usr/bin/python
from onl.platform.base import *
class OnlPlatformDelta(OnlPlatformBase):
MANUFACTURER='Delta'
PRIVATE_ENTERPRISE_NUMBER=2254

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/arch-vendor-modules.yml ARCH=amd64 VENDOR=delta 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 := $(wildcard *.c)
VENDOR := delta
BASENAME := common
ARCH := x86_64
include $(ONL)/make/kmodule.mk

View File

@@ -0,0 +1,515 @@
/*
* I2C for CPLD
*
* Copyright (C) 2017 Delta network Technology Corporation.
* Masan Xu <masan.xu@deltaww.com>
*
* This module supports cpld that read and write.
*
* Based on:
* i2c_x86-64-agc7648-cpld.c from Aaron Chang <aaron.mh.chang@deltaww.com>
* Copyright (C) 2017 Delta network Technology Corporation.
*
* Based on:
* pca954x.c from Kumar Gala <galak@kernel.crashing.org>
* Copyright (C) 2006
*
* Based on:
* pca954x.c from Ken Harrenstien
* Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
*
* Based on:
* i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
* and
* pca9540.c from Jean Delvare <khali@linux-fr.org>.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/dmi.h>
#include <linux/version.h>
#include <linux/ctype.h>
#define NUM_OF_CPLD1_CHANS 0x0
#define I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD1_CHANS
static struct dmi_system_id cpld_dmi_table[] =
{
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "DELTA"),
},
},
};
static LIST_HEAD(cpld_client_list);
static struct mutex list_lock;
static unsigned char gReg = 0;
struct cpld_client_node
{
struct i2c_client *client;
struct list_head list;
};
enum cpld_mux_type
{
cpld
};
struct i2c_cpld_mux
{
enum cpld_mux_type type;
struct i2c_adapter *virt_adaps[I2C_CPLD_MUX_MAX_NCHANS];
u8 last_chan; /* last register value */
};
struct chip_desc
{
u8 nchans;
u8 deselectChan;
};
/* Provide specs for the PCA954x types we know about */
static const struct chip_desc chips[] =
{
[cpld] = {
.nchans = NUM_OF_CPLD1_CHANS,
.deselectChan = NUM_OF_CPLD1_CHANS,
},
};
static const struct i2c_device_id i2c_cpld_mux_id[] =
{
{ "cpld", cpld },
{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_cpld_mux_id);
int platform_cpld(void)
{
return dmi_check_system(cpld_dmi_table);
}
EXPORT_SYMBOL(platform_cpld);
/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
for this as they will try to lock adapter a second time */
static int i2c_cpld_mux_reg_write(struct i2c_adapter *adap,
struct i2c_client *client, u8 val)
{
unsigned long orig_jiffies;
unsigned short flags;
union i2c_smbus_data data;
int try;
s32 res = -EIO;
data.byte = val;
flags = client->flags;
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
if (adap->algo->smbus_xfer)
{
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
for (res = 0, try = 0;
try <= adap->retries;
try++)
{
res = adap->algo->smbus_xfer(adap, client->addr, flags,
I2C_SMBUS_WRITE, 0x2,
I2C_SMBUS_BYTE_DATA, &data);
if (res != -EAGAIN)
{
break;
}
if (time_after(jiffies,
orig_jiffies + adap->timeout))
{
break;
}
}
}
return res;
}
static int i2c_cpld_mux_select_chan(struct i2c_adapter *adap,
void *client, u32 chan)
{
struct i2c_cpld_mux *data = i2c_get_clientdata(client);
u8 regval;
int ret = 0;
regval = chan;
/* Only select the channel if its different from the last channel */
if (data->last_chan != regval)
{
ret = i2c_cpld_mux_reg_write(adap, client, regval);
data->last_chan = regval;
}
return ret;
}
static int i2c_cpld_mux_deselect_mux(struct i2c_adapter *adap,
void *client, u32 chan)
{
struct i2c_cpld_mux *data = i2c_get_clientdata(client);
/* Deselect active channel */
data->last_chan = chips[data->type].deselectChan;
//return i2c_cpld_mux_reg_write(adap, client, data->last_chan);
i2c_cpld_mux_reg_write(adap, client, data->last_chan);
return 0;
}
static void i2c_cpld_add_client(struct i2c_client *client)
{
struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node),
GFP_KERNEL);
if (!node)
{
dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr);
return;
}
node->client = client;
mutex_lock(&list_lock);
list_add(&node->list, &cpld_client_list);
mutex_unlock(&list_lock);
}
static void i2c_cpld_remove_client(struct i2c_client *client)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int found = 0;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if (cpld_node->client == client)
{
found = 1;
break;
}
}
if (found)
{
list_del(list_node);
kfree(cpld_node);
}
mutex_unlock(&list_lock);
}
static ssize_t
set_cpld_reg(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned int val;
char *endp;
val = simple_strtoul(buf, &endp, 16);
if (isspace(*endp))
{
endp++;
}
if (endp - buf != count)
{
return -1;
}
if (val > 255)
{
return -1;
}
gReg = val;
return count;
}
static ssize_t get_cpld_reg(struct device *dev, struct device_attribute *attr,
char *buf)
{
int len;
len = sprintf(buf, "0x%x\n", gReg);
return len;
}
static ssize_t
set_cpld_data(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client;
unsigned int val;
char *endp;
char ret = -1;
val = simple_strtoul(buf, &endp, 16);
if (isspace(*endp))
{
endp++;
}
if (endp - buf != count)
{
return -1;
}
if (val > 255)
{
return -1;
}
mutex_lock(&list_lock);
client = to_i2c_client(dev);
ret = i2c_smbus_write_byte_data(client, gReg, val);
mutex_unlock(&list_lock);
return count;
}
static ssize_t
get_cpld_data(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client;
int len;
client = to_i2c_client(dev);
len = sprintf(buf, "0x%x\n", i2c_smbus_read_byte_data(client, gReg));
return len;
}
static struct device_attribute gData = __ATTR(data, 0600, get_cpld_data,
set_cpld_data);
static struct device_attribute gAddr = __ATTR(addr, 0600, get_cpld_reg,
set_cpld_reg);
static ssize_t show_cpld_version(struct device *dev,
struct device_attribute *attr, char *buf)
{
u8 reg = 0x1;
struct i2c_client *client;
int len;
client = to_i2c_client(dev);
len = sprintf(buf, "%d\n", i2c_smbus_read_byte_data(client, reg));
return len;
}
static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version,
NULL);
/*
* I2C init/probing/exit functions
*/
static int i2c_cpld_mux_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
int chan = 0;
struct i2c_cpld_mux *data;
int ret = -ENODEV;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
{
goto err;
}
data = kzalloc(sizeof(struct i2c_cpld_mux), GFP_KERNEL);
if (!data)
{
ret = -ENOMEM;
goto err;
}
i2c_set_clientdata(client, data);
data->type = id->driver_data;
data->last_chan =
chips[data->type].deselectChan; /* force the first selection */
/* Now create an adapter for each channel */
for (chan = 0; chan < chips[data->type].nchans; chan++)
{
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0,
chan,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
I2C_CLASS_HWMON | I2C_CLASS_SPD,
#endif
i2c_cpld_mux_select_chan,
i2c_cpld_mux_deselect_mux);
if (data->virt_adaps[chan] == NULL)
{
ret = -ENODEV;
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
goto virt_reg_failed;
}
}
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
chan, client->name);
i2c_cpld_add_client(client);
ret = sysfs_create_file(&client->dev.kobj, &ver.attr);
if (ret)
{
goto virt_reg_failed;
}
ret = sysfs_create_file(&client->dev.kobj, &gData.attr);
if (ret)
{
goto virt_reg_failed;
}
ret = sysfs_create_file(&client->dev.kobj, &gAddr.attr);
if (ret)
{
goto virt_reg_failed;
}
return 0;
virt_reg_failed:
for (chan--; chan >= 0; chan--)
{
i2c_del_mux_adapter(data->virt_adaps[chan]);
}
kfree(data);
err:
return ret;
}
static int i2c_cpld_mux_remove(struct i2c_client *client)
{
struct i2c_cpld_mux *data = i2c_get_clientdata(client);
const struct chip_desc *chip = &chips[data->type];
int chan;
sysfs_remove_file(&client->dev.kobj, &ver.attr);
for (chan = 0; chan < chip->nchans; ++chan)
{
if (data->virt_adaps[chan])
{
i2c_del_mux_adapter(data->virt_adaps[chan]);
data->virt_adaps[chan] = NULL;
}
}
kfree(data);
i2c_cpld_remove_client(client);
return 0;
}
int i2c_cpld_read(int bus, unsigned short cpld_addr, u8 reg)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int ret = -EPERM;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if ((cpld_node->client->adapter->nr == bus) &&
(cpld_node->client->addr == cpld_addr) )
{
ret = i2c_smbus_read_byte_data(cpld_node->client, reg);
break;
}
}
mutex_unlock(&list_lock);
return ret;
}
EXPORT_SYMBOL(i2c_cpld_read);
int i2c_cpld_write(int bus, unsigned short cpld_addr, u8 reg, u8 value)
{
struct list_head *list_node = NULL;
struct cpld_client_node *cpld_node = NULL;
int ret = -EIO;
mutex_lock(&list_lock);
list_for_each(list_node, &cpld_client_list)
{
cpld_node = list_entry(list_node, struct cpld_client_node, list);
if ((cpld_node->client->adapter->nr == bus) &&
(cpld_node->client->addr == cpld_addr) )
{
ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value);
break;
}
}
mutex_unlock(&list_lock);
return ret;
}
EXPORT_SYMBOL(i2c_cpld_write);
static struct i2c_driver i2c_cpld_mux_driver =
{
.driver = {
.name = "cpld",
.owner = THIS_MODULE,
},
.probe = i2c_cpld_mux_probe,
.remove = i2c_cpld_mux_remove,
.id_table = i2c_cpld_mux_id,
};
static int __init i2c_cpld_mux_init(void)
{
mutex_init(&list_lock);
return i2c_add_driver(&i2c_cpld_mux_driver);
}
static void __exit i2c_cpld_mux_exit(void)
{
i2c_del_driver(&i2c_cpld_mux_driver);
}
MODULE_AUTHOR("masan.xu@deltaww.com");
MODULE_DESCRIPTION("I2C CPLD mux driver");
MODULE_LICENSE("GPL");
module_init(i2c_cpld_mux_init);
module_exit(i2c_cpld_mux_exit);

View File

@@ -0,0 +1,3 @@
*x86*64*delta_agc7648a*.mk
onlpdump.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=delta BASENAME=x86-64-delta-agc7648a ARCH=amd64 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 := $(wildcard *.c)
VENDOR := delta
BASENAME := x86-64-delta-agc7648a
ARCH := x86_64
include $(ONL)/make/kmodule.mk

View File

@@ -0,0 +1,565 @@
/*
* An hwmon driver for agc7648a PSU
* dps_800ab_16_d.c - Support for DPS-800AB-16 D Power Supply Module
*
* Copyright (C) 2017 Delta Networks, Inc.
* Masan Xu <masan.xu@deltaww.com>
*
* Based on:
* dni_ag9032v1_psu.c from Aries Lin <aries.lin@deltaww.com>
* Copyright (C) 2016 Delta Network Technology Corporation
*
* Based on:
* ym2651y.c
* ad7414.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#define MAX_FAN_DUTY_CYCLE 100
#define PSU1_MUX_VAL 0x00
#define PSU2_MUX_VAL 0x02
#define MUX_SELECT(MUX_VAL) i2c_cpld_write(5, 0x30, 0x1f, MUX_VAL)
u8 select_psu_num = 1;
/* Address scanned */
static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END };
/* This is additional data */
struct dps_800ab_16_d_data {
struct device *hwmon_dev;
struct mutex update_lock;
char valid;
unsigned long last_updated; /* In jiffies */
/* Registers value */
u8 vout_mode;
u16 v_in;
u16 v_out;
u16 i_in;
u16 i_out;
u16 p_in;
u16 p_out;
u16 temp_input[2];
u8 fan_fault;
u16 fan_duty_cycle[2];
u16 fan_speed[2];
u8 mfr_model[16];
u8 mfr_serial[16];
};
static int two_complement_to_int(u16 data, u8 valid_bit, int mask);
static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count);
static ssize_t for_linear_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
static ssize_t for_fan_fault(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
static ssize_t for_vout_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
static int dps_800ab_16_d_read_byte(struct i2c_client *client, u8 reg);
static int dps_800ab_16_d_read_word(struct i2c_client *client, u8 reg);
static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \
u16 value);
static int dps_800ab_16_d_read_block(struct i2c_client *client, u8 command, \
u8 *data, int data_len);
static struct dps_800ab_16_d_data *dps_800ab_16_d_update_device( \
struct device *dev);
static ssize_t for_ascii(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
static ssize_t set_w_member_data(struct device *dev, struct device_attribute \
*dev_att, const char *buf, size_t count);
static ssize_t for_r_member_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
extern int i2c_cpld_write(int bus, unsigned short cpld_addr, u8 reg, u8 value);
enum dps_800ab_16_d_sysfs_attributes {
PSU_V_IN,
PSU_V_OUT,
PSU_I_IN,
PSU_I_OUT,
PSU_P_IN,
PSU_P_OUT,
PSU_TEMP1_INPUT,
PSU_FAN1_FAULT,
PSU_FAN1_DUTY_CYCLE,
PSU_FAN1_SPEED,
PSU_MFR_MODEL,
PSU_MFR_SERIAL,
PSU_SELECT_MEMBER,
};
static ssize_t set_w_member_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
long data;
int error;
if (attr->index == PSU_SELECT_MEMBER) {
error = kstrtol(buf, 10, &data);
if (error)
return error;
if (data == 1) {
select_psu_num = 1;
/* Select PSU MUX */
MUX_SELECT(PSU1_MUX_VAL);
} else if (data == 2) {
select_psu_num = 2;
/* Select PSU MUX */
MUX_SELECT(PSU2_MUX_VAL);
} else {
return -EINVAL;
}
}
return count;
}
static ssize_t for_r_member_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
return sprintf(buf, "%d\n", select_psu_num);
}
static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
{
u16 valid_data = data & mask;
bool is_negative = valid_data >> (valid_bit - 1);
return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data;
}
static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
struct i2c_client *client = to_i2c_client(dev);
struct dps_800ab_16_d_data *data = i2c_get_clientdata(client);
int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1;
long speed;
int error;
error = kstrtol(buf, 10, &speed);
if (error)
return error;
if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE)
return -EINVAL;
/* Select PSU MUX */
if(select_psu_num == 1){
MUX_SELECT(PSU1_MUX_VAL);
}else if(select_psu_num == 2){
MUX_SELECT(PSU2_MUX_VAL);
}else{
return -EINVAL;
}
mutex_lock(&data->update_lock);
data->fan_duty_cycle[nr] = speed;
dps_800ab_16_d_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t for_linear_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev);
u16 value = 0;
int exponent, mantissa;
int multiplier = 1000;
switch (attr->index) {
case PSU_V_IN:
value = data->v_in;
break;
case PSU_I_IN:
value = data->i_in;
break;
case PSU_I_OUT:
value = data->i_out;
break;
case PSU_P_IN:
value = data->p_in;
break;
case PSU_P_OUT:
value = data->p_out;
break;
case PSU_TEMP1_INPUT:
value = data->temp_input[0];
break;
case PSU_FAN1_DUTY_CYCLE:
multiplier = 1;
value = data->fan_duty_cycle[0];
break;
case PSU_FAN1_SPEED:
multiplier = 1;
value = data->fan_speed[0];
break;
default:
break;
}
exponent = two_complement_to_int(value >> 11, 5, 0x1f);
mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff);
return (exponent >= 0) ? sprintf(buf, "%d\n", \
(mantissa << exponent) * multiplier) : \
sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
}
static ssize_t for_fan_fault(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev);
u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6;
return sprintf(buf, "%d\n", data->fan_fault >> shift);
}
static ssize_t for_vout_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev);
int exponent, mantissa;
int multiplier = 1000;
exponent = two_complement_to_int(data->vout_mode, 5, 0x1f);
mantissa = data->v_out;
return (exponent > 0) ? sprintf(buf, "%d\n", \
(mantissa << exponent) * multiplier) : \
sprintf(buf, "%d\n", (mantissa << exponent) / (1 << -exponent));
}
static ssize_t for_ascii(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev);
u8 *ptr = NULL;
if (!data->valid)
return 0;
switch (attr->index) {
case PSU_MFR_MODEL:
ptr = data->mfr_model + 1;
break;
case PSU_MFR_SERIAL:
ptr = data->mfr_serial + 1;
break;
default:
return 0;
}
return sprintf(buf, "%s\n", ptr);
}
static int dps_800ab_16_d_read_byte(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
static int dps_800ab_16_d_read_word(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_word_data(client, reg);
}
static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \
u16 value)
{
union i2c_smbus_data data;
data.word = value;
return i2c_smbus_xfer(client->adapter, client->addr,
client->flags |= I2C_CLIENT_PEC,
I2C_SMBUS_WRITE, reg,
I2C_SMBUS_WORD_DATA, &data);
}
static int dps_800ab_16_d_read_block(struct i2c_client *client, u8 command, \
u8 *data, int data_len)
{
int result = i2c_smbus_read_i2c_block_data(client, command, data_len,
data);
if (unlikely(result < 0))
goto abort;
if (unlikely(result != data_len)) {
result = -EIO;
goto abort;
}
result = 0;
abort:
return result;
}
struct reg_data_byte {
u8 reg;
u8 *value;
};
struct reg_data_word {
u8 reg;
u16 *value;
};
static struct dps_800ab_16_d_data *dps_800ab_16_d_update_device( \
struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct dps_800ab_16_d_data *data = i2c_get_clientdata(client);
mutex_lock(&data->update_lock);
/* Select PSU MUX */
if(select_psu_num == 1){
MUX_SELECT(PSU1_MUX_VAL);
}else if(select_psu_num == 2){
MUX_SELECT(PSU2_MUX_VAL);
}else{
return -EINVAL;
}
if (time_after(jiffies, data->last_updated)) {
int i, status;
u8 command;
struct reg_data_byte regs_byte[] = {
{0x20, &data->vout_mode},
{0x81, &data->fan_fault}
};
struct reg_data_word regs_word[] = {
{0x88, &data->v_in},
{0x8b, &data->v_out},
{0x89, &data->i_in},
{0x8c, &data->i_out},
{0x96, &data->p_out},
{0x97, &data->p_in},
{0x8d, &(data->temp_input[0])},
{0x8e, &(data->temp_input[1])},
{0x3b, &(data->fan_duty_cycle[0])},
{0x90, &(data->fan_speed[0])},
};
dev_dbg(&client->dev, "start data update\n");
/* one milliseconds from now */
data->last_updated = jiffies + HZ / 1000;
for (i = 0; i < ARRAY_SIZE(regs_byte); i++) {
status = dps_800ab_16_d_read_byte(client,
regs_byte[i].reg);
if (status < 0) {
dev_dbg(&client->dev, "reg %d, err %d\n",
regs_byte[i].reg, status);
} else {
*(regs_byte[i].value) = status;
}
}
for (i = 0; i < ARRAY_SIZE(regs_word); i++) {
status = dps_800ab_16_d_read_word(client,
regs_word[i].reg);
if (status < 0) {
dev_dbg(&client->dev, "reg %d, err %d\n",
regs_word[i].reg, status);
} else {
*(regs_word[i].value) = status;
}
}
command = 0x9a; /* PSU mfr_model */
status = dps_800ab_16_d_read_block(client, command,
data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1);
data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0';
if (status < 0) {
dev_dbg(&client->dev, "reg %d, err %d\n", command,
status);
}
command = 0x9e; /* PSU mfr_serial */
status = dps_800ab_16_d_read_block(client, command,
data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1);
data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0';
if (status < 0) {
dev_dbg(&client->dev, "reg %d, err %d\n", command,
status);
}
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
/* sysfs attributes for hwmon */
static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN);
static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT);
static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN);
static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT);
static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN);
static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT);
static SENSOR_DEVICE_ATTR(psu_temp1_input, \
S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(psu_fan1_fault, \
S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT);
static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUGO | S_IRUGO, \
for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE);
static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, \
S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED);
static SENSOR_DEVICE_ATTR(psu_mfr_model, \
S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL);
static SENSOR_DEVICE_ATTR(psu_mfr_serial, \
S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL);
static SENSOR_DEVICE_ATTR(psu_select_member, S_IWUGO | S_IRUGO, \
for_r_member_data, set_w_member_data, PSU_SELECT_MEMBER);
static struct attribute *dps_800ab_16_d_attributes[] = {
&sensor_dev_attr_psu_v_in.dev_attr.attr,
&sensor_dev_attr_psu_v_out.dev_attr.attr,
&sensor_dev_attr_psu_i_in.dev_attr.attr,
&sensor_dev_attr_psu_i_out.dev_attr.attr,
&sensor_dev_attr_psu_p_in.dev_attr.attr,
&sensor_dev_attr_psu_p_out.dev_attr.attr,
&sensor_dev_attr_psu_temp1_input.dev_attr.attr,
&sensor_dev_attr_psu_fan1_fault.dev_attr.attr,
&sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr,
&sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr,
&sensor_dev_attr_psu_mfr_model.dev_attr.attr,
&sensor_dev_attr_psu_mfr_serial.dev_attr.attr,
&sensor_dev_attr_psu_select_member.dev_attr.attr,
NULL
};
static const struct attribute_group dps_800ab_16_d_group = {
.attrs = dps_800ab_16_d_attributes,
};
static int dps_800ab_16_d_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct dps_800ab_16_d_data *data;
int status;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->valid = 0;
mutex_init(&data->update_lock);
dev_info(&client->dev, "new chip found\n");
/* Register sysfs hooks */
status = sysfs_create_group(&client->dev.kobj, &dps_800ab_16_d_group);
if (status)
goto exit_sysfs_create_group;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_hwmon_device_register;
}
return 0;
exit_hwmon_device_register:
sysfs_remove_group(&client->dev.kobj, &dps_800ab_16_d_group);
exit_sysfs_create_group:
kfree(data);
exit:
return status;
}
static int dps_800ab_16_d_remove(struct i2c_client *client)
{
struct dps_800ab_16_d_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &dps_800ab_16_d_group);
kfree(data);
return 0;
}
enum id_name {
agc7648a_dps800ab
};
static const struct i2c_device_id dps_800ab_16_d_id[] = {
{ "agc7648a_dps800ab", agc7648a_dps800ab },
{}
};
MODULE_DEVICE_TABLE(i2c, dps_800ab_16_d_id);
/* This is the driver that will be inserted */
static struct i2c_driver dps_800ab_16_d_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "dps_800ab_16_d",
},
.probe = dps_800ab_16_d_probe,
.remove = dps_800ab_16_d_remove,
.id_table = dps_800ab_16_d_id,
.address_list = normal_i2c,
};
static int __init dps_800ab_16_d_init(void)
{
return i2c_add_driver(&dps_800ab_16_d_driver);
}
static void __exit dps_800ab_16_d_exit(void)
{
i2c_del_driver(&dps_800ab_16_d_driver);
}
MODULE_AUTHOR("masan.xu@deltaww.com");
MODULE_DESCRIPTION("DPS_800AB_16_D Driver");
MODULE_LICENSE("GPL");
module_init(dps_800ab_16_d_init);
module_exit(dps_800ab_16_d_exit);

View File

@@ -0,0 +1,325 @@
/*
* <bsn.cl fy=2013 v=gpl>
*
* Copyright (C) 2017 Delta Networks, Inc.
* Masan Xu <masan.xu@deltaww.com>
*
* Based on:
* dni_emc2305.c from Aaron Chang <aaron.mh.chang@deltaww.com>
* Copyright (C) 2017 Delta Networks, Inc.
*
* Based on:
* emc2305.c
* Copyright 2013, 2014 BigSwitch Networks, Inc.
*
* This program is free software; you can redistribute it
* and/or modify it under the terms ofthe GNU General Public License as
* published by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
*
* </bsn.cl>
*
*
* A hwmon driver for the SMSC EMC2305 fan controller
* Complete datasheet is available (6/2013) at:
* http://www.smsc.com/media/Downloads_Public/Data_Sheets/2305.pdf
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
extern int i2c_cpld_read(int bus, unsigned short cpld_addr, u8 reg);
extern int i2c_cpld_write(int bus, unsigned short cpld_addr, u8 reg, u8 value);
static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count);
static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
char *buf);
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
char *buf);
static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count);
static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, 0x2F, 0x4C,
0x4D, I2C_CLIENT_END
};
#define EMC2305_REG_DEVICE 0xFD
#define EMC2305_REG_VENDOR 0xFE
//#define FAN_MINIMUN 0x33 /*20%*/
#define FAN_MINIMUN 0x0 /*0%*/
#define FAN_RPM_BASED 0xAB
#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * n)
#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n)
#define EMC2305_REG_FAN_TACH(n) (0x3E + 0x10 * n)
#define EMC2305_REG_FAN_CONF(n) (0x32 + 0x10 * n)
#define EMC2305_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n)
#define EMC2305_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n)
#define EMC2305_DEVICE 0x34
#define EMC2305_VENDOR 0x5D
#define MUX_SELECT i2c_cpld_write(5, 0x30, 0x67, 0x05)
struct emc2305_data
{
struct device *hwmon_dev;
struct attribute_group attrs;
struct mutex lock;
};
static int emc2305_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int emc2305_detect(struct i2c_client *client,
struct i2c_board_info *info);
static int emc2305_remove(struct i2c_client *client);
static const struct i2c_device_id emc2305_id[] =
{
{ "agc7648a_emc2305", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, emc2305_id);
static struct i2c_driver emc2305_driver =
{
.class = I2C_CLASS_HWMON,
.driver = {
.name = "agc7648a_emc2305",
},
.probe = emc2305_probe,
.remove = emc2305_remove,
.id_table = emc2305_id,
.detect = emc2305_detect,
.address_list = normal_i2c,
};
static SENSOR_DEVICE_ATTR(fan1_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 0);
static SENSOR_DEVICE_ATTR(fan2_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 1);
static SENSOR_DEVICE_ATTR(fan3_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 2);
static SENSOR_DEVICE_ATTR(fan4_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 3);
static SENSOR_DEVICE_ATTR(fan5_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 4);
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3);
static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4);
static struct attribute *emc2305_attr[] =
{
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
&sensor_dev_attr_fan4_input.dev_attr.attr,
&sensor_dev_attr_fan5_input.dev_attr.attr,
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm4.dev_attr.attr,
&sensor_dev_attr_pwm5.dev_attr.attr,
NULL
};
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct emc2305_data *data = i2c_get_clientdata(client);
int val;
MUX_SELECT;
mutex_lock(&data->lock);
val = i2c_smbus_read_word_swapped(client,
EMC2305_REG_FAN_TACH(attr->index));
mutex_unlock(&data->lock);
/* Left shift 3 bits for showing correct RPM */
val = val >> 3;
return sprintf(buf, "%d\n", 3932160 * 2 / (val > 0 ? val : 1));
}
static ssize_t set_fan(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 emc2305_data *data = i2c_get_clientdata(client);
unsigned long hsb, lsb;
unsigned long tech;
unsigned long val;
int ret;
MUX_SELECT;
ret = kstrtoul(buf, 10, &val);
if (ret)
{
return ret;
}
if (val > 23000)
{
return -EINVAL;
}
if (val <= 960)
{
hsb = 0xff; /*high bit*/
lsb = 0xe0; /*low bit*/
}
else
{
tech = (3932160 * 2) / (val > 0 ? val : 1);
hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff);
lsb = (uint8_t)((tech << 3) & 0x0f8);
}
mutex_lock(&data->lock);
i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb);
i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_L_RPM(attr->index), lsb);
mutex_unlock(&data->lock);
return count;
}
static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct emc2305_data *data = i2c_get_clientdata(client);
int val;
MUX_SELECT;
mutex_lock(&data->lock);
val = i2c_smbus_read_byte_data(client,
EMC2305_REG_FAN_DRIVE(attr->index));
mutex_unlock(&data->lock);
return sprintf(buf, "%d\n", val);
}
static ssize_t set_pwm(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 emc2305_data *data = i2c_get_clientdata(client);
unsigned long val;
int ret;
MUX_SELECT;
ret = kstrtoul(buf, 10, &val);
if (ret)
{
return ret;
}
if (val > 255)
{
return -EINVAL;
}
mutex_lock(&data->lock);
i2c_smbus_write_byte_data(client,
EMC2305_REG_FAN_DRIVE(attr->index),
val);
mutex_unlock(&data->lock);
return count;
}
static int emc2305_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int vendor, device;
MUX_SELECT;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
{
return -ENODEV;
}
vendor = i2c_smbus_read_byte_data(client, EMC2305_REG_VENDOR);
if (vendor != EMC2305_VENDOR)
{
return -ENODEV;
}
device = i2c_smbus_read_byte_data(client, EMC2305_REG_DEVICE);
if (device != EMC2305_DEVICE)
{
return -ENODEV;
}
strlcpy(info->type, "emc2305", I2C_NAME_SIZE);
return 0;
}
static int emc2305_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct emc2305_data *data;
int err;
int i;
data = devm_kzalloc(&client->dev, sizeof(struct emc2305_data),
GFP_KERNEL);
if (!data)
{
return -ENOMEM;
}
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
dev_info(&client->dev, "%s chip found\n", client->name);
data->attrs.attrs = emc2305_attr;
err = sysfs_create_group(&client->dev.kobj, &data->attrs);
if (err)
{
return err;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev))
{
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
for (i = 0; i < 5; i++)
{
/* set minimum drive to 0% */
i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN);
i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_CONF(i), FAN_RPM_BASED);
}
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return err;
}
static int emc2305_remove(struct i2c_client *client)
{
struct emc2305_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return 0;
}
module_i2c_driver(emc2305_driver);
MODULE_AUTHOR("masan.xu@deltaww.com");
MODULE_DESCRIPTION("SMSC EMC2305 fan controller driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,677 @@
/*
* An hwmon driver for agc7648a sfp
*
* Copyright (C) 2017 Delta Networks, Inc.
* Aries Lin <aries.lin@deltaww.com>
*
* Based on:
* ad7414.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#define I2C_BUS_5 5
#define SWPLD_U21 0x30
#define SWPLD_U134 0x31
#define SWPLD_U215 0x32
#define SFP_PRESENCE_1 0x30
#define SFP_PRESENCE_2 0x31
#define SFP_PRESENCE_3 0x32
#define SFP_PRESENCE_4 0x33
#define SFP_PRESENCE_5 0x34
#define SFP_PRESENCE_6 0x35
#define QSFP_PRESENCE_1 0x63
#define QSFP_LP_MODE_1 0x62
#define QSFP_RESET_1 0x3C
#define DEFAULT_DISABLE 0x00
#define QSFP_DEFAULT_DISABLE 0x1F
#define QSFP_SEL_I2C_MUX 0x20
#define SFP_SEL_I2C_MUX 0x21
/* Check cpld read results */
#define VALIDATED_READ(_buf, _rv, _read, _invert) \
do { \
_rv = _read; \
if (_rv < 0) { \
return sprintf(_buf, "READ ERROR\n"); \
} \
if (_invert) { \
_rv = ~_rv; \
} \
_rv &= 0xFF; \
} while(0) \
int sfp_port_data = 0;
static const u8 cpld_to_port_table[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
/* Addresses scanned */
static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
/* Each client has this additional data */
struct agc7648a_sfp_data {
struct device *hwmon_dev;
struct mutex update_lock;
char valid;
unsigned long last_updated;
int port;
char eeprom[256];
};
static ssize_t for_eeprom(struct device *dev, struct device_attribute *dev_attr,
char *buf);
static int agc7648a_sfp_read_block(struct i2c_client *client, u8 command,
u8 *data, int data_len);
static struct agc7648a_sfp_data *agc7648a_sfp_update_device( \
struct device *dev);
static ssize_t for_status(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
static ssize_t set_w_port_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count);
static ssize_t for_r_port_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf);
static ssize_t set_w_lp_mode_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count);
static ssize_t set_w_reset_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count);
extern int i2c_cpld_read(int bus, unsigned short cpld_addr, u8 reg);
extern int i2c_cpld_write(int bus, unsigned short cpld_addr, u8 reg, u8 value);
enum agc7648a_sfp_sysfs_attributes {
SFP_EEPROM,
SFP_SELECT_PORT,
SFP_IS_PRESENT,
SFP_IS_PRESENT_ALL,
SFP_LP_MODE,
SFP_RESET
};
static ssize_t set_w_port_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count)
{
long data;
int error;
u8 port_t = 0;
u8 reg_t = 0x00;
error = kstrtol(buf, 10, &data);
if (error)
return error;
port_t = data;
if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */
reg_t = QSFP_SEL_I2C_MUX;
} else {
/* Disable SFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, SFP_SEL_I2C_MUX,
DEFAULT_DISABLE) < 0) {
return -EIO;
}
/* Disable QSFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, QSFP_SEL_I2C_MUX,
QSFP_DEFAULT_DISABLE) < 0) {
return -EIO;
}
goto exit;
}
/* Disable SFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, SFP_SEL_I2C_MUX,
DEFAULT_DISABLE) < 0) {
return -EIO;
}
/* Disable QSFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, QSFP_SEL_I2C_MUX,
QSFP_DEFAULT_DISABLE) < 0) {
return -EIO;
}
/* Select SFP or QSFP port channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, reg_t,
cpld_to_port_table[port_t]) < 0) {
return -EIO;
}
exit:
sfp_port_data = data;
return count;
}
static ssize_t for_r_port_data(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
if (sfp_port_data == DEFAULT_DISABLE) {
/* Disable SFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134,
SFP_SEL_I2C_MUX, DEFAULT_DISABLE) < 0) {
return -EIO;
}
/* Disable QSFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134,
QSFP_SEL_I2C_MUX, QSFP_DEFAULT_DISABLE) < 0) {
return -EIO;
}
}
return sprintf(buf, "%d\n", sfp_port_data);
}
static ssize_t set_w_lp_mode_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count)
{
long data;
int error;
u8 port_t = 0;
int bit_t = 0x00;
int values = 0x00;
error = kstrtol(buf, 10, &data);
if (error)
return error;
port_t = sfp_port_data;
if (port_t > 47 && port_t < 54) { /* QSFP Port 48-53 */
values = i2c_cpld_read(I2C_BUS_5, SWPLD_U21, QSFP_LP_MODE_1);
if (values < 0)
return -EIO;
/* Indicate the module is in LP mode or not
* 0 = Disable
* 1 = Enable
*/
if (data == 0) {
bit_t = ~(1 << ((port_t - 1) % 8));
values = values & bit_t;
} else if (data == 1) {
bit_t = 1 << ((port_t - 1) % 8);
values = values | bit_t;
} else {
return -EINVAL;
}
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U21, QSFP_LP_MODE_1,
values) < 0) {
return -EIO;
}
}
return count;
}
static ssize_t set_w_reset_data(struct device *dev, struct device_attribute \
*dev_attr, const char *buf, size_t count)
{
long data;
int error;
u8 port_t = 0;
int bit_t = 0x00;
int values = 0x00;
error = kstrtol(buf, 10, &data);
if (error)
return error;
port_t = sfp_port_data;
if (port_t > 47 && port_t < 54) { /* QSFP Port 48-53 */
values = i2c_cpld_read(I2C_BUS_5, SWPLD_U21, QSFP_RESET_1);
if (values < 0)
return -EIO;
/* Indicate the module Reset or not
* 0 = Reset
* 1 = Normal
*/
if (data == 0) {
bit_t = ~(1 << ((port_t - 1) % 8));
values = values & bit_t;
} else if (data == 1) {
bit_t = 1 << ((port_t - 1) % 8);
values = values | bit_t;
} else {
return -EINVAL;
}
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U21, QSFP_RESET_1,
values) < 0) {
return -EIO;
}
}
return count;
}
static ssize_t for_status(struct device *dev, struct device_attribute \
*dev_attr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
u8 port_t = 0;
u8 reg_t = 0x00;
u8 cpld_addr_t = 0x00;
int values[7] = {'\0'};
int bit_t = 0x00;
switch (attr->index) {
case SFP_IS_PRESENT:
port_t = sfp_port_data;
if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */
cpld_addr_t = SWPLD_U215;
reg_t = SFP_PRESENCE_1;
} else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */
cpld_addr_t = SWPLD_U215;
reg_t = SFP_PRESENCE_2;
} else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */
cpld_addr_t = SWPLD_U215;
reg_t = SFP_PRESENCE_3;
} else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */
cpld_addr_t = SWPLD_U215;
reg_t = SFP_PRESENCE_4;
} else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */
cpld_addr_t = SWPLD_U215;
reg_t = SFP_PRESENCE_5;
} else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */
cpld_addr_t = SWPLD_U215;
reg_t = SFP_PRESENCE_6;
} else if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */
cpld_addr_t = SWPLD_U21;
reg_t = QSFP_PRESENCE_1;
} else {
values[0] = 1; /* return 1, module NOT present */
return sprintf(buf, "%d\n", values[0]);
}
VALIDATED_READ(buf, values[0], i2c_cpld_read(I2C_BUS_5,
cpld_addr_t, reg_t), 0);
/* SWPLD QSFP module respond */
bit_t = 1 << ((port_t - 1) % 8);
values[0] = values[0] & bit_t;
values[0] = values[0] / bit_t;
/* sfp_is_present value
* return 0 is module present
* return 1 is module NOT present
*/
return sprintf(buf, "%d\n", values[0]);
case SFP_IS_PRESENT_ALL:
/*
* Report the SFP ALL PRESENCE status
* This data information form CPLD.
*/
/* SFP_PRESENT Ports 1-8 */
VALIDATED_READ(buf, values[0],
i2c_cpld_read(I2C_BUS_5, SWPLD_U215, SFP_PRESENCE_1), 0);
/* SFP_PRESENT Ports 9-16 */
VALIDATED_READ(buf, values[1],
i2c_cpld_read(I2C_BUS_5, SWPLD_U215, SFP_PRESENCE_2), 0);
/* SFP_PRESENT Ports 17-24 */
VALIDATED_READ(buf, values[2],
i2c_cpld_read(I2C_BUS_5, SWPLD_U215, SFP_PRESENCE_3), 0);
/* SFP_PRESENT Ports 25-32 */
VALIDATED_READ(buf, values[3],
i2c_cpld_read(I2C_BUS_5, SWPLD_U215, SFP_PRESENCE_4), 0);
/* SFP_PRESENT Ports 33-40 */
VALIDATED_READ(buf, values[4],
i2c_cpld_read(I2C_BUS_5, SWPLD_U215, SFP_PRESENCE_5), 0);
/* SFP_PRESENT Ports 41-48 */
VALIDATED_READ(buf, values[5],
i2c_cpld_read(I2C_BUS_5, SWPLD_U215, SFP_PRESENCE_6), 0);
/* QSFP_PRESENT Ports 49-54 */
VALIDATED_READ(buf, values[6],
i2c_cpld_read(I2C_BUS_5, SWPLD_U21, QSFP_PRESENCE_1), 0);
/* sfp_is_present_all value
* return 0 is module present
* return 1 is module NOT present
*/
return sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X\n",
values[0], values[1], values[2],
values[3], values[4], values[5],
values[6]);
case SFP_LP_MODE:
port_t = sfp_port_data;
if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */
VALIDATED_READ(buf, values[0], i2c_cpld_read(I2C_BUS_5,
SWPLD_U21, QSFP_LP_MODE_1), 0);
} else {
/* In AGC7648 only QSFP support control LP MODE */
values[0] = 0;
return sprintf(buf, "%d\n", values[0]);
}
/* SWPLD QSFP module respond */
bit_t = 1 << ((port_t - 1) % 8);
values[0] = values[0] & bit_t;
values[0] = values[0] / bit_t;
/* sfp_lp_mode value
* return 0 is module NOT in LP mode
* return 1 is module in LP mode
*/
return sprintf(buf, "%d\n", values[0]);
case SFP_RESET:
port_t = sfp_port_data;
if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */
VALIDATED_READ(buf, values[0], i2c_cpld_read(I2C_BUS_5,
SWPLD_U21, QSFP_RESET_1), 0);
} else {
/* In AGC7648 only QSFP support control RESET MODE */
values[0] = 1;
return sprintf(buf, "%d\n", values[0]);
}
/* SWPLD QSFP module respond */
bit_t = 1 << ((port_t - 1) % 8);
values[0] = values[0] & bit_t;
values[0] = values[0] / bit_t;
/* sfp_reset value
* return 0 is module Reset
* return 1 is module Normal
*/
return sprintf(buf, "%d\n", values[0]);
default:
return (attr->index);
}
}
static ssize_t for_eeprom(struct device *dev, struct device_attribute *dev_attr,
char *buf)
{
struct agc7648a_sfp_data *data = agc7648a_sfp_update_device(dev);
if (!data->valid) {
return 0;
}
memcpy(buf, data->eeprom, sizeof(data->eeprom));
return sizeof(data->eeprom);
}
static int agc7648a_sfp_read_block(struct i2c_client *client, u8 command, \
u8 *data, int data_len)
{
int result = i2c_smbus_read_i2c_block_data(client, command, data_len,
data);
if (unlikely(result < 0))
goto abort;
if (unlikely(result != data_len)) {
result = -EIO;
goto abort;
}
result = 0;
abort:
return result;
}
static struct agc7648a_sfp_data *agc7648a_sfp_update_device( \
struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct agc7648a_sfp_data *data = i2c_get_clientdata(client);
u8 port_t = 0;
u8 reg_t = 0x00;
port_t = sfp_port_data;
memset(data->eeprom, 0, sizeof(data->eeprom));
if (port_t > 0 && port_t < 9) { /* SFP Port 1-8 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 8 && port_t < 17) { /* SFP Port 9-16 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 16 && port_t < 25) { /* SFP Port 17-24 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 24 && port_t < 33) { /* SFP Port 25-32 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 32 && port_t < 41) { /* SFP Port 33-40 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 40 && port_t < 49) { /* SFP Port 41-48 */
reg_t = SFP_SEL_I2C_MUX;
} else if (port_t > 48 && port_t < 55) { /* QSFP Port 49-54 */
reg_t = QSFP_SEL_I2C_MUX;
} else {
memset(data->eeprom, 0, sizeof(data->eeprom));
/* Disable SFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, SFP_SEL_I2C_MUX,
DEFAULT_DISABLE) < 0) {
goto exit;
}
/* Disable QSFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, QSFP_SEL_I2C_MUX,
QSFP_DEFAULT_DISABLE) < 0) {
goto exit;
}
goto exit;
}
/* Disable SFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, SFP_SEL_I2C_MUX,
DEFAULT_DISABLE) < 0) {
memset(data->eeprom, 0, sizeof(data->eeprom));
goto exit;
}
/* Disable QSFP channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, QSFP_SEL_I2C_MUX,
QSFP_DEFAULT_DISABLE) < 0) {
memset(data->eeprom, 0, sizeof(data->eeprom));
goto exit;
}
/* Select SFP or QSFP port channel */
if (i2c_cpld_write(I2C_BUS_5, SWPLD_U134, reg_t,
cpld_to_port_table[port_t]) < 0) {
memset(data->eeprom, 0, sizeof(data->eeprom));
goto exit;
}
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated) || !data->valid) {
int status = -1;
int i = 0;
data->valid = 0;
memset(data->eeprom, 0, sizeof(data->eeprom));
for (i = 0; i < sizeof(data->eeprom)/ \
I2C_SMBUS_BLOCK_MAX; i++) {
status = agc7648a_sfp_read_block(
client,
i * I2C_SMBUS_BLOCK_MAX,
data->eeprom + (i * I2C_SMBUS_BLOCK_MAX),
I2C_SMBUS_BLOCK_MAX
);
if (status < 0) {
printk(KERN_INFO "status = %d\n", status);
dev_dbg(&client->dev,
"unable to read eeprom from port(%d)\n", data->port);
goto exit;
}
}
data->last_updated = jiffies;
data->valid = 1;
}
exit:
mutex_unlock(&data->update_lock);
return data;
}
/* sysfs attributes for hwmon */
static SENSOR_DEVICE_ATTR(sfp_eeprom, S_IRUGO, for_eeprom, NULL,
SFP_EEPROM);
static SENSOR_DEVICE_ATTR(sfp_select_port, S_IWUSR | S_IRUGO,
for_r_port_data, set_w_port_data, SFP_SELECT_PORT);
static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, for_status, NULL,
SFP_IS_PRESENT);
static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, for_status, NULL,
SFP_IS_PRESENT_ALL);
static SENSOR_DEVICE_ATTR(sfp_lp_mode, S_IWUSR | S_IRUGO,
for_status, set_w_lp_mode_data, SFP_LP_MODE);
static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO,
for_status, set_w_reset_data, SFP_RESET);
static struct attribute *agc7648a_sfp_attributes[] = {
&sensor_dev_attr_sfp_eeprom.dev_attr.attr,
&sensor_dev_attr_sfp_select_port.dev_attr.attr,
&sensor_dev_attr_sfp_is_present.dev_attr.attr,
&sensor_dev_attr_sfp_is_present_all.dev_attr.attr,
&sensor_dev_attr_sfp_lp_mode.dev_attr.attr,
&sensor_dev_attr_sfp_reset.dev_attr.attr,
NULL
};
static const struct attribute_group agc7648a_sfp_group = {
.attrs = agc7648a_sfp_attributes,
};
static int agc7648a_sfp_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct agc7648a_sfp_data *data;
int status;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_I2C_BLOCK)) {
status = -EIO;
goto exit;
}
data = kzalloc(sizeof(struct agc7648a_sfp_data), GFP_KERNEL);
if (!data) {
status = -ENOMEM;
goto exit;
}
mutex_init(&data->update_lock);
data->port = id->driver_data;
i2c_set_clientdata(client, data);
dev_info(&client->dev, "chip found\n");
status = sysfs_create_group(&client->dev.kobj, &agc7648a_sfp_group);
if (status)
goto exit_sysfs_create_group;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_hwmon_device_register;
}
dev_info(&client->dev, "%s: sfp '%s'\n", dev_name(data->hwmon_dev),
client->name);
return 0;
exit_hwmon_device_register:
sysfs_remove_group(&client->dev.kobj, &agc7648a_sfp_group);
exit_sysfs_create_group:
kfree(data);
exit:
return status;
}
static int agc7648a_sfp_remove(struct i2c_client *client)
{
struct agc7648a_sfp_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &agc7648a_sfp_group);
kfree(data);
return 0;
}
enum id_name {
agc7648a_sfp
};
static const struct i2c_device_id agc7648a_sfp_id[] = {
{ "agc7648a_sfp", agc7648a_sfp },
{}
};
MODULE_DEVICE_TABLE(i2c, agc7648a_sfp_id);
static struct i2c_driver agc7648a_sfp_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "agc7648a_sfp",
},
.probe = agc7648a_sfp_probe,
.remove = agc7648a_sfp_remove,
.id_table = agc7648a_sfp_id,
.address_list = normal_i2c,
};
static int __init agc7648a_sfp_init(void)
{
return i2c_add_driver(&agc7648a_sfp_driver);
}
static void __exit agc7648a_sfp_exit(void)
{
i2c_del_driver(&agc7648a_sfp_driver);
}
MODULE_AUTHOR("Aries Lin <aries.lin@deltaww.com>");
MODULE_DESCRIPTION("agc7648a SFP Driver");
MODULE_LICENSE("GPL");
module_init(agc7648a_sfp_init);
module_exit(agc7648a_sfp_exit);

View File

@@ -0,0 +1,309 @@
/* tmp421.c
*
* Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
* Preliminary support by:
* Melvin Rook, Raymond Ng
*
* 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.
*/
/*
* Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
* Supported models: TMP421, TMP422, TMP423
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
I2C_CLIENT_END };
enum chips { tmp421, tmp422, tmp423 };
/* The TMP421 registers */
#define TMP421_CONFIG_REG_1 0x09
#define TMP421_CONVERSION_RATE_REG 0x0B
#define TMP421_MANUFACTURER_ID_REG 0xFE
#define TMP421_DEVICE_ID_REG 0xFF
static const u8 TMP421_TEMP_MSB[4] = { 0x00, 0x01, 0x02, 0x03 };
static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 };
/* Flags */
#define TMP421_CONFIG_SHUTDOWN 0x40
#define TMP421_CONFIG_RANGE 0x04
/* Manufacturer / Device ID's */
#define TMP421_MANUFACTURER_ID 0x55
#define TMP421_DEVICE_ID 0x21
#define TMP422_DEVICE_ID 0x22
#define TMP423_DEVICE_ID 0x23
static const struct i2c_device_id tmp421_id[] = {
{ "tmp421", 2 },
{ "tmp422", 3 },
{ "tmp423", 4 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tmp421_id);
struct tmp421_data {
struct i2c_client *client;
struct mutex update_lock;
char valid;
unsigned long last_updated;
int channels;
u8 config;
s16 temp[4];
};
static int temp_from_s16(s16 reg)
{
/* Mask out status bits */
int temp = reg & ~0xf;
return (temp * 1000 + 128) / 256;
}
static int temp_from_u16(u16 reg)
{
/* Mask out status bits */
int temp = reg & ~0xf;
/* Add offset for extended temperature range. */
temp -= 64 * 256;
return (temp * 1000 + 128) / 256;
}
static struct tmp421_data *tmp421_update_device(struct device *dev)
{
struct tmp421_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int i;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
data->config = i2c_smbus_read_byte_data(client,
TMP421_CONFIG_REG_1);
for (i = 0; i < data->channels; i++) {
data->temp[i] = i2c_smbus_read_byte_data(client,
TMP421_TEMP_MSB[i]) << 8;
data->temp[i] |= i2c_smbus_read_byte_data(client,
TMP421_TEMP_LSB[i]);
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static ssize_t show_temp_value(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct tmp421_data *data = tmp421_update_device(dev);
int temp;
mutex_lock(&data->update_lock);
if (data->config & TMP421_CONFIG_RANGE)
temp = temp_from_u16(data->temp[index]);
else
temp = temp_from_s16(data->temp[index]);
mutex_unlock(&data->update_lock);
return sprintf(buf, "%d\n", temp);
}
static ssize_t show_fault(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct tmp421_data *data = tmp421_update_device(dev);
/*
* The OPEN bit signals a fault. This is bit 0 of the temperature
* register (low byte).
*/
if (data->temp[index] & 0x01)
return sprintf(buf, "1\n");
else
return sprintf(buf, "0\n");
}
static umode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct tmp421_data *data = dev_get_drvdata(dev);
struct device_attribute *devattr;
unsigned int index;
devattr = container_of(a, struct device_attribute, attr);
index = to_sensor_dev_attr(devattr)->index;
if (index < data->channels)
return a->mode;
return 0;
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
static struct attribute *tmp421_attr[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp3_fault.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr,
&sensor_dev_attr_temp4_fault.dev_attr.attr,
NULL
};
static const struct attribute_group tmp421_group = {
.attrs = tmp421_attr,
.is_visible = tmp421_is_visible,
};
static const struct attribute_group *tmp421_groups[] = {
&tmp421_group,
NULL
};
static int tmp421_init_client(struct i2c_client *client)
{
int config, config_orig;
/* Set the conversion rate to 2 Hz */
i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05);
/* Start conversions (disable shutdown if necessary) */
config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1);
if (config < 0) {
dev_err(&client->dev,
"Could not read configuration register (%d)\n", config);
return config;
}
config_orig = config;
config &= ~TMP421_CONFIG_SHUTDOWN;
if (config != config_orig) {
dev_info(&client->dev, "Enable monitoring chip\n");
i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config);
}
return 0;
}
static int tmp421_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
enum chips kind;
struct i2c_adapter *adapter = client->adapter;
const char *names[] = { "TMP421", "TMP422", "TMP423" };
u8 reg;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
reg = i2c_smbus_read_byte_data(client, TMP421_MANUFACTURER_ID_REG);
if (reg != TMP421_MANUFACTURER_ID)
return -ENODEV;
reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
switch (reg) {
case TMP421_DEVICE_ID:
kind = tmp421;
break;
case TMP422_DEVICE_ID:
kind = tmp422;
break;
case TMP423_DEVICE_ID:
kind = tmp423;
break;
default:
return -ENODEV;
}
strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
names[kind], client->addr);
return 0;
}
static int tmp421_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct device *hwmon_dev;
struct tmp421_data *data;
int err;
data = devm_kzalloc(dev, sizeof(struct tmp421_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
mutex_init(&data->update_lock);
data->channels = id->driver_data;
data->client = client;
err = tmp421_init_client(client);
if (err)
return err;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data, tmp421_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static struct i2c_driver tmp421_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "tmp421",
},
.probe = tmp421_probe,
.id_table = tmp421_id,
.detect = tmp421_detect,
.address_list = normal_i2c,
};
module_i2c_driver(tmp421_driver);
MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-delta-agc7648a ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu

View File

@@ -0,0 +1,2 @@
FILTER=src
include $(ONL)/make/subdirs.mk

View File

@@ -0,0 +1,45 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# 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 $(ONL)/make/config.amd64.mk
MODULE := libonlp-x86-64-delta-agc7648a
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF x86_64_delta_agc7648a onlplib
DEPENDMODULE_HEADERS := sff
include $(BUILDER)/dependmodules.mk
SHAREDLIB := libonlp-x86-64-delta-agc7648a.so
$(SHAREDLIB)_TARGETS := $(ALL_TARGETS)
include $(BUILDER)/so.mk
.DEFAULT_GOAL := $(SHAREDLIB)
GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -fPIC
GLOBAL_LINK_LIBS += -lpthread
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the libonlp-x86-64-delta-agc7648a module.
#
# Autogenerated 2017-03-15 04:06:44.303111
#
###############################################################################
libonlp-x86-64-delta-agc7648a_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1,46 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# 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 $(ONL)/make/config.amd64.mk
.DEFAULT_GOAL := onlpdump
MODULE := onlpdump
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF onlp x86_64_delta_agc7648a onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS
include $(BUILDER)/dependmodules.mk
BINARY := onlpdump
$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS)
include $(BUILDER)/bin.mk
GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1
GLOBAL_LINK_LIBS += -lpthread -lm
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1 @@
name: x86_64_delta_agc7648a

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
include ../../init.mk
MODULE := x86_64_delta_agc7648a
AUTOMODULE := x86_64_delta_agc7648a
include $(BUILDER)/definemodule.mk

View File

@@ -0,0 +1,6 @@
###############################################################################
#
# x86_64_delta_agc7648a README
#
###############################################################################

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# x86_64_delta_agc7648a Autogeneration
#
###############################################################################
x86_64_delta_agc7648a_AUTO_DEFS := module/auto/x86_64_delta_agc7648a.yml
x86_64_delta_agc7648a_AUTO_DIRS := module/inc/x86_64_delta_agc7648a module/src
include $(BUILDER)/auto.mk

View File

@@ -0,0 +1,50 @@
###############################################################################
#
# x86_64_delta_agc7648a Autogeneration Definitions.
#
###############################################################################
cdefs: &cdefs
- X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING:
doc: "Include or exclude logging."
default: 1
- X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT:
doc: "Default enabled log options."
default: AIM_LOG_OPTIONS_DEFAULT
- X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT:
doc: "Default enabled log bits."
default: AIM_LOG_BITS_DEFAULT
- X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT:
doc: "Default enabled custom log bits."
default: 0
- X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB:
doc: "Default all porting macros to use the C standard libraries."
default: 1
- X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS:
doc: "Include standard library headers for stdlib porting macros."
default: X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB
- X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI:
doc: "Include generic uCli support."
default: 0
- X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION:
doc: "Assume chassis fan direction is the same as the PSU fan direction."
default: 0
definitions:
cdefs:
X86_64_DELTA_AGC7648A_CONFIGHEADER:
defs: *cdefs
basename: x86_64_delta_agc7648a_config
portingmacro:
x86_64_delta_agc7648a:
macros:
- malloc
- free
- memset
- memcpy
- strncpy
- vsnprintf
- snprintf
- strlen

View File

@@ -0,0 +1,14 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
/* <--auto.start.xmacro(ALL).define> */
/* <auto.end.xmacro(ALL).define> */
/* <--auto.start.xenum(ALL).define> */
/* <auto.end.xenum(ALL).define> */

View File

@@ -0,0 +1,137 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_agc7648a Configuration Header
*
* @addtogroup x86_64_delta_agc7648a-config
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_AGC7648A_CONFIGH__
#define __X86_64_DELTA_AGC7648A_CONFIGH__
#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG
#include <global_custom_config.h>
#endif
#ifdef x86_64_delta_agc7648a_INCLUDE_CUSTOM_CONFIG
#include <x86_64_delta_agc7648a_custom_config.h>
#endif
/* <auto.start.cdefs(X86_64_DELTA_AGC7648A_CONFIGHEADER).header> */
#include <AIM/aim.h>
/**
* X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING
*
* Include or exclude logging. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING
#define X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING 1
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT
*
* Default enabled log options. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT
#define X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT
*
* Default enabled log bits. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT
#define X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT
*
* Default enabled custom log bits. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT
#define X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT 0
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB
*
* Default all porting macros to use the C standard libraries. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB
#define X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB 1
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS
*
* Include standard library headers for stdlib porting macros. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS
#define X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI
*
* Include generic uCli support. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI
#define X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI 0
#endif
/**
* X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION
*
* Assume chassis fan direction is the same as the PSU fan direction. */
#ifndef X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION
#define X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION 0
#endif
/**
* All compile time options can be queried or displayed
*/
/** Configuration settings structure. */
typedef struct x86_64_delta_agc7648a_config_settings_s {
/** name */
const char* name;
/** value */
const char* value;
} x86_64_delta_agc7648a_config_settings_t;
/** Configuration settings table. */
/** x86_64_delta_agc7648a_config_settings table. */
extern x86_64_delta_agc7648a_config_settings_t x86_64_delta_agc7648a_config_settings[];
/**
* @brief Lookup a configuration setting.
* @param setting The name of the configuration option to lookup.
*/
const char* x86_64_delta_agc7648a_config_lookup(const char* setting);
/**
* @brief Show the compile-time configuration.
* @param pvs The output stream.
*/
int x86_64_delta_agc7648a_config_show(struct aim_pvs_s* pvs);
/* <auto.end.cdefs(X86_64_DELTA_AGC7648A_CONFIGHEADER).header> */
#include "x86_64_delta_agc7648a_porting.h"
#endif /* __X86_64_DELTA_AGC7648A_CONFIGH__ */
/* @} */

View File

@@ -0,0 +1,26 @@
/**************************************************************************//**
*
* x86_64_delta_agc7648a Doxygen Header
*
*****************************************************************************/
#ifndef __x86_64_delta_agc7648a_DOX_H__
#define __x86_64_delta_agc7648a_DOX_H__
/**
* @defgroup x86_64_delta_agc7648a x86_64_delta_agc7648a - x86_64_delta_agc7648a Description
*
The documentation overview for this module should go here.
*
* @{
*
* @defgroup x86_64_delta_agc7648a-x86_64_delta_agc7648a Public Interface
* @defgroup x86_64_delta_agc7648a-config Compile Time Configuration
* @defgroup x86_64_delta_agc7648a-porting Porting Macros
*
* @}
*
*/
#endif /* __x86_64_delta_agc7648a_DOX_H__ */

View File

@@ -0,0 +1,107 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_agc7648a Porting Macros.
*
* @addtogroup x86_64_delta_agc7648a-porting
* @{
*
*****************************************************************************/
#ifndef __x86_64_delta_agc7648a_PORTING_H__
#define __x86_64_delta_agc7648a_PORTING_H__
/* <auto.start.portingmacro(ALL).define> */
#if X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS == 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <memory.h>
#endif
#ifndef x86_64_delta_agc7648a_MALLOC
#if defined(GLOBAL_MALLOC)
#define x86_64_delta_agc7648a_MALLOC GLOBAL_MALLOC
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_MALLOC malloc
#else
#error The macro x86_64_delta_agc7648a_MALLOC is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_FREE
#if defined(GLOBAL_FREE)
#define x86_64_delta_agc7648a_FREE GLOBAL_FREE
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_FREE free
#else
#error The macro x86_64_delta_agc7648a_FREE is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_MEMSET
#if defined(GLOBAL_MEMSET)
#define x86_64_delta_agc7648a_MEMSET GLOBAL_MEMSET
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_MEMSET memset
#else
#error The macro x86_64_delta_agc7648a_MEMSET is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_MEMCPY
#if defined(GLOBAL_MEMCPY)
#define x86_64_delta_agc7648a_MEMCPY GLOBAL_MEMCPY
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_MEMCPY memcpy
#else
#error The macro x86_64_delta_agc7648a_MEMCPY is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_STRNCPY
#if defined(GLOBAL_STRNCPY)
#define x86_64_delta_agc7648a_STRNCPY GLOBAL_STRNCPY
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_STRNCPY strncpy
#else
#error The macro x86_64_delta_agc7648a_STRNCPY is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_VSNPRINTF
#if defined(GLOBAL_VSNPRINTF)
#define x86_64_delta_agc7648a_VSNPRINTF GLOBAL_VSNPRINTF
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_VSNPRINTF vsnprintf
#else
#error The macro x86_64_delta_agc7648a_VSNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_SNPRINTF
#if defined(GLOBAL_SNPRINTF)
#define x86_64_delta_agc7648a_SNPRINTF GLOBAL_SNPRINTF
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_SNPRINTF snprintf
#else
#error The macro x86_64_delta_agc7648a_SNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef x86_64_delta_agc7648a_STRLEN
#if defined(GLOBAL_STRLEN)
#define x86_64_delta_agc7648a_STRLEN GLOBAL_STRLEN
#elif X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB == 1
#define x86_64_delta_agc7648a_STRLEN strlen
#else
#error The macro x86_64_delta_agc7648a_STRLEN is required but cannot be defined.
#endif
#endif
/* <auto.end.portingmacro(ALL).define> */
#endif /* __x86_64_delta_agc7648a_PORTING_H__ */
/* @} */

View File

@@ -0,0 +1,10 @@
###############################################################################
#
#
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_delta_agc7648a_INCLUDES := -I $(THIS_DIR)inc
x86_64_delta_agc7648a_INTERNAL_INCLUDES := -I $(THIS_DIR)src
x86_64_delta_agc7648a_DEPENDMODULE_ENTRIES := init:x86_64_delta_agc7648a ucli:x86_64_delta_agc7648a

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# Local source generation targets.
#
###############################################################################
ucli:
@../../../../tools/uclihandlers.py x86_64_delta_agc7648a_ucli.c

View File

@@ -0,0 +1,45 @@
#include "x86_64_delta_agc7648a_int.h"
#if X86_64_DELTA_AGC7648A_CONFIG_INCLUDE_DEBUG == 1
#include <unistd.h>
static char help__[] =
"Usage: debug [options]\n"
" -c CPLD Versions\n"
" -h Help\n"
;
int
x86_64_delta_agc7648a_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

@@ -0,0 +1,389 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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 <onlp/platformi/fani.h>
#include <onlplib/mmap.h>
#include <fcntl.h>
#include "platform_lib.h"
#include <onlplib/i2c.h>
typedef struct fan_path_S
{
char *status;
char *speed;
char *ctrl_speed;
}fan_path_T;
static fan_path_T fan_path[] = /* must map with onlp_fan_id in platform_lib.h */
{
{ NULL, NULL, NULL },
{ "3-002c/fan1_fault", "3-002c/fan1_input", "3-002c/fan1_input" },
{ "3-002c/fan2_fault", "3-002c/fan2_input", "3-002c/fan2_input" },
{ "3-002c/fan3_fault", "3-002c/fan3_input", "3-002c/fan3_input" },
{ "3-002c/fan4_fault", "3-002c/fan4_input", "3-002c/fan4_input" },
{ "3-002d/fan1_fault", "3-002d/fan1_input", "3-002d/fan1_input" },
{ "3-002d/fan2_fault", "3-002d/fan2_input", "3-002d/fan2_input" },
{ "3-002d/fan3_fault", "3-002d/fan3_input", "3-002d/fan3_input" },
{ "3-002d/fan4_fault", "3-002d/fan4_input", "3-002d/fan4_input" },
{ "4-0058/psu_fan1_fault", "4-0058/psu_fan1_speed_rpm", "4-0058/psu_fan1_duty_cycle_percentage" },
{ "4-0058/psu_fan1_fault", "4-0058/psu_fan1_speed_rpm", "4-0058/psu_fan1_duty_cycle_percentage" }
};
#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_RPM | ONLP_FAN_CAPS_GET_RPM), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
}
#define MAKE_FAN_INFO_NODE_ON_PSU(psu_id, 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), \
0, \
0, \
ONLP_FAN_MODE_INVALID, \
}
/* Static fan information */
onlp_fan_info_t linfo[] = {
{ }, /* Not used */
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(1),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(2),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(3),
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),
};
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_FAN(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
static int
dni_fani_info_get_fan(int local_id, onlp_fan_info_t* info)
{
int rpm = 0;
char fullpath[100] = {0};
/* Update fan rpm */
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, fan_path[local_id].speed);
rpm = dni_i2c_lock_read_attribute(NULL, fullpath);
/* If rpm equal FAN_ZERO_TACH meaning 0 */
if(rpm == FAN_ZERO_TACH)
{
rpm = 0;
}
info->rpm = rpm;
/* Update fan speed percentage based from rpm */
switch(local_id)
{
case FAN_1_ON_MAIN_BOARD:
case FAN_2_ON_MAIN_BOARD:
case FAN_3_ON_MAIN_BOARD:
case FAN_4_ON_MAIN_BOARD:
info->percentage = (info->rpm * 100)/MAX_FRONT_FAN_SPEED;
break;
case FAN_5_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
case FAN_7_ON_MAIN_BOARD:
case FAN_8_ON_MAIN_BOARD:
info->percentage = (info->rpm * 100)/MAX_REAR_FAN_SPEED;
break;
default:
AIM_LOG_ERROR("Error local_id");
break;
}
/* Update present bit of fan status */
mux_info_t mux_info;
mux_info.bus = I2C_BUS_5;
mux_info.addr = SWPLD;
mux_info.offset = FAN_MUX_REG;
mux_info.channel = 0x07;
dev_info_t dev_info;
dev_info.bus = I2C_BUS_3;
dev_info.addr = FAN_IO_CTRL;
dev_info.offset = 0x00;
dev_info.size = 1;
dev_info.flags = 0;
int fantray_present_val = dni_i2c_lock_read(&mux_info, &dev_info);
switch(local_id)
{
case FAN_1_ON_MAIN_BOARD:
case FAN_5_ON_MAIN_BOARD:
if((fantray_present_val & 0x01) == 0x00)
info->status |= ONLP_FAN_STATUS_PRESENT;
break;
case FAN_2_ON_MAIN_BOARD:
case FAN_6_ON_MAIN_BOARD:
if((fantray_present_val & 0x02) == 0x00)
info->status |= ONLP_FAN_STATUS_PRESENT;
break;
case FAN_3_ON_MAIN_BOARD:
case FAN_7_ON_MAIN_BOARD:
if((fantray_present_val & 0x04) == 0x00)
info->status |= ONLP_FAN_STATUS_PRESENT;
break;
case FAN_4_ON_MAIN_BOARD:
case FAN_8_ON_MAIN_BOARD:
if((fantray_present_val & 0x08) == 0x00)
info->status |= ONLP_FAN_STATUS_PRESENT;
break;
}
return ONLP_STATUS_OK;
}
static int
dni_fani_info_get_fan_on_psu(int local_id, onlp_fan_info_t* info)
{
int r_data = 0, psu_present_val = 0;
char fullpath[80] = {0}, psu_num[2];
/* Read cpld psu present bit for updating psu present status */
psu_present_val = dni_lock_cpld_read_attribute(SWPLD_PATH, PSU_PRESENT_REG);
if(local_id == FAN_1_ON_PSU1 &&
((psu_present_val & 0x01) == 0x00))
{
info->status |= ONLP_FAN_STATUS_PRESENT;
}
else if(local_id == FAN_1_ON_PSU2 &&
((psu_present_val & 0x02) == 0x00))
{
info->status |= ONLP_FAN_STATUS_PRESENT;
}
/* Configure MUX settings */
if(local_id == FAN_1_ON_PSU1)
{
sprintf(psu_num, "%d", 1);
}
else if(local_id == FAN_1_ON_PSU2)
{
sprintf(psu_num, "%d", 2);
}
/* Set MUX */
dni_i2c_lock_write_attribute(NULL, psu_num, PSU_SEL_PATH);
/* Get psu fan fault status */
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, fan_path[local_id].status);
r_data = dni_i2c_lock_read_attribute(NULL, fullpath);
if (r_data > 0)
info->status |= ONLP_FAN_STATUS_FAILED;
/* Get psu fan rpm */
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, fan_path[local_id].speed);
r_data = dni_i2c_lock_read_attribute(NULL, fullpath);
info->rpm = r_data;
/* Calculate psu fan duty cycle based on rpm */
info->percentage = (info->rpm * 100) / MAX_PSU_FAN_SPEED;
return ONLP_STATUS_OK;
}
/*
* This function will be called prior to all of onlp_fani_* functions.
*/
int
onlp_fani_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
{
int rc = 0;
int local_id;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
*info = linfo[local_id];
switch (local_id)
{
case FAN_1_ON_PSU1:
case FAN_1_ON_PSU2:
rc = dni_fani_info_get_fan_on_psu(local_id, info);
break;
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:
rc = dni_fani_info_get_fan(local_id, info);
break;
default:
rc = ONLP_STATUS_E_INVALID;
break;
}
return rc;
}
/*
* This function sets the speed of the given fan in RPM.
*
* This function will only be called if the fan supprots the RPM_SET
* capability.
*
* It is optional if you have no fans at all with this feature.
*/
int
onlp_fani_rpm_set(onlp_oid_t id, int rpm)
{
int local_id;
char data[10] = {0};
char fullpath[256] = {0};
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
/* get fullpath */
switch (local_id)
{
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:
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, fan_path[local_id].ctrl_speed);
break;
default:
return ONLP_STATUS_E_INVALID;
}
sprintf(data, "%d", rpm);
dni_i2c_lock_write_attribute(NULL, data, fullpath);
return ONLP_STATUS_OK;
}
/*
* This function sets the fan speed of the given OID as a percentage.
*
* This will only be called if the OID has the PERCENTAGE_SET
* capability.
*
* It is optional if you have no fans at all with this feature.
*/
int
onlp_fani_percentage_set(onlp_oid_t id, int p)
{
int local_id;
char data[10], fullpath[256] = {0}, psu_num[2];
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
/* Configure MUX settings and fan percentage attribute path */
switch(local_id)
{
case FAN_1_ON_PSU1:
sprintf(psu_num, "%d", 1);
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, fan_path[local_id].ctrl_speed);
break;
case FAN_1_ON_PSU2:
sprintf(psu_num, "%d", 2);
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, fan_path[local_id].ctrl_speed);
break;
default:
return ONLP_STATUS_E_INVALID;
}
/* Set MUX */
dni_i2c_lock_write_attribute(NULL, psu_num, PSU_SEL_PATH);
/* Set fan percentage */
sprintf(data, "%d", p);
dni_i2c_lock_write_attribute(NULL, data, fullpath);
return ONLP_STATUS_OK;
}
/*
* This function sets the fan speed of the given OID as per
* the predefined ONLP fan speed modes: off, slow, normal, fast, max.
*
* Interpretation of these modes is up to the platform.
*
*/
int
onlp_fani_mode_set(onlp_oid_t id, onlp_fan_mode_t mode)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* This function sets the fan direction of the given OID.
*
* This function is only relevant if the fan OID supports both direction
* capabilities.
*
* This function is optional unless the functionality is available.
*/
int
onlp_fani_dir_set(onlp_oid_t id, onlp_fan_dir_t dir)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* Generic fan ioctl. Optional.
*/
int
onlp_fani_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,426 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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 <fcntl.h>
#include <onlplib/mmap.h>
#include <onlplib/i2c.h>
#include "platform_lib.h"
#define ALL_FAN_TRAY_EXIST 4
#define PREFIX_PATH_ON_BOARD "/sys/bus/i2c/devices/"
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_LED(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
/*
* Get the information for the given LED OID.
*/
static onlp_led_info_t linfo[] =
{
{ }, /* Not used */
{
{ ONLP_LED_ID_CREATE(LED_FRONT_FAN), "FRONT LED (FAN LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_FRONT_SYS), "FRONT LED (SYS LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_FRONT_PWR), "FRONT LED (PWR LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_ORANGE_BLINKING | ONLP_LED_CAPS_GREEN,
},
{
{ ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_1), "REAR LED (FAN TRAY 1)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_2), "REAR LED (FAN TRAY 2)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_3), "REAR LED (FAN TRAY 3)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_4), "REAR LED (FAN TRAY 4)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_AUTO,
}
};
/*
* This function will be called prior to any other onlp_ledi_* functions.
*/
int
onlp_ledi_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
{
int r_data = 0, r_data1 = 0, fantray_present = -1;
VALIDATE(id);
/* Set the onlp_oid_hdr_t and capabilities */
*info = linfo[ONLP_OID_ID_GET(id)];
mux_info_t mux_info;
mux_info.bus = I2C_BUS_5;
mux_info.addr = SWPLD;
mux_info.offset = FAN_MUX_REG;
mux_info.channel = 0x07;
mux_info.flags = DEFAULT_FLAG;
dev_info_t dev_info;
dev_info.bus = I2C_BUS_3;
dev_info.offset = 0x00;
dev_info.flags = DEFAULT_FLAG;
/* Set front panel's mode of leds */
r_data = dni_lock_cpld_read_attribute(SWPLD_PATH, LED_REG);
r_data1 = dni_lock_cpld_read_attribute(SWPLD_PATH, FAN_TRAY_LED_REG);
int local_id = ONLP_OID_ID_GET(id);
switch(local_id)
{
case LED_FRONT_FAN:
if((r_data & 0x02) == 0x02)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data & 0x01) == 0x01)
info->mode = ONLP_LED_MODE_ORANGE;
break;
case LED_FRONT_SYS:
if((r_data & 0x10) == 0x10)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data & 0x20) == 0x20)
info->mode = ONLP_LED_MODE_ORANGE;
else
return ONLP_STATUS_E_INTERNAL;
break;
case LED_FRONT_PWR:
if((r_data & 0x08) == 0x08)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data & 0x04) == 0x04)
info->mode = ONLP_LED_MODE_ORANGE;
else
info->mode = ONLP_LED_MODE_OFF;
break;
case LED_REAR_FAN_TRAY_1:
mux_info.channel= 0x00;
dev_info.addr = FAN_TRAY_1;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
if(fantray_present >= 0)
{
if((r_data1 & 0x40) == 0x40)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data1 & 0x80) == 0x80)
info->mode = ONLP_LED_MODE_ORANGE;
}
else
info->mode = ONLP_LED_MODE_OFF;
break;
case LED_REAR_FAN_TRAY_2:
mux_info.channel= 0x01;
dev_info.addr = FAN_TRAY_2;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
if(fantray_present >= 0)
{
if((r_data1 & 0x10) == 0x10)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data1 & 0x20) == 0x20)
info->mode = ONLP_LED_MODE_ORANGE;
}
else
info->mode = ONLP_LED_MODE_OFF;
break;
case LED_REAR_FAN_TRAY_3:
mux_info.channel= 0x02;
dev_info.addr = FAN_TRAY_3;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
if(fantray_present >= 0)
{
if((r_data1 & 0x04) == 0x04)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data1 & 0x08) == 0x08)
info->mode = ONLP_LED_MODE_ORANGE;
}
else
info->mode = ONLP_LED_MODE_OFF;
break;
case LED_REAR_FAN_TRAY_4:
mux_info.channel= 0x03;
dev_info.addr = FAN_TRAY_4;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
if(fantray_present >= 0)
{
if((r_data1 & 0x01) == 0x01)
info->mode = ONLP_LED_MODE_GREEN;
else if((r_data1 & 0x02) == 0x02)
info->mode = ONLP_LED_MODE_ORANGE;
}
else
info->mode = ONLP_LED_MODE_OFF;
break;
default:
break;
}
/* Set the on/off status */
if (info->mode == ONLP_LED_MODE_OFF) {
info->status |= ONLP_LED_STATUS_FAILED;
} else {
info->status |=ONLP_LED_STATUS_PRESENT;
}
return ONLP_STATUS_OK;
}
/*
* Turn an LED on or off.
*
* This function will only be called if the LED OID supports the ONOFF
* capability.
*
* What 'on' means in terms of colors or modes for multimode LEDs is
* up to the platform to decide. This is intended as baseline toggle mechanism.
*/
int
onlp_ledi_set(onlp_oid_t id, int on_or_off)
{
VALIDATE(id);
if(on_or_off == 0)
onlp_ledi_mode_set(id, ONLP_LED_MODE_OFF);
else
onlp_ledi_mode_set(id,ONLP_LED_MODE_AUTO);
return ONLP_STATUS_OK;
}
/*
* This function puts the LED into the given mode. It is a more functional
* interface for multimode LEDs.
*
* Only modes reported in the LED's capabilities will be attempted.
*/
int
onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
{
VALIDATE(id);
int local_id = ONLP_OID_ID_GET(id);
int i = 0, count = 0 ;
int fantray_present = -1 ,rpm = 0,rpm1 = 0;
uint8_t front_panel_led_value, fan_tray_led_value, power_state;
mux_info_t mux_info;
mux_info.bus = I2C_BUS_5;
mux_info.addr = SWPLD;
mux_info.offset = FAN_MUX_REG;
mux_info.channel = 0x07;
mux_info.flags = DEFAULT_FLAG;
dev_info_t dev_info;
dev_info.bus = I2C_BUS_3;
dev_info.offset = 0x00;
dev_info.flags = DEFAULT_FLAG;
front_panel_led_value = dni_lock_cpld_read_attribute(SWPLD_PATH,LED_REG);
fan_tray_led_value = dni_lock_cpld_read_attribute(SWPLD_PATH,FAN_TRAY_LED_REG);
switch(local_id)
{
case LED_FRONT_FAN:
/* Clean the bit 1,0 */
front_panel_led_value &= ~0x3;
/* Read fan eeprom to check present */
for(i = 0;i < 4; i++)
{
mux_info.channel = i;
/* FAN TRAT 1~4: 0x52 , 0x53, 0x54, 0x55 */
dev_info.addr = FAN_TRAY_1 + i;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
if( fantray_present >= 0 )
count++;
}
/* Set front light of FAN */
if(count == ALL_FAN_TRAY_EXIST)
{
front_panel_led_value|=0x02;
dni_lock_cpld_write_attribute(SWPLD_PATH, LED_REG, front_panel_led_value);
}
else
{
front_panel_led_value|=0x01;
dni_lock_cpld_write_attribute(SWPLD_PATH, LED_REG, front_panel_led_value);
}
break;
case LED_FRONT_PWR:
/* Clean bit 3,2 */
front_panel_led_value &= ~0x0C;
/* switch CPLD to PSU 1 */
dev_info.bus = I2C_BUS_4;
dev_info.addr = PSU_EEPROM;
mux_info.channel = 0x00;
/* Check the state of PSU 1, "state = 1, PSU exists' */
power_state = dni_lock_cpld_read_attribute(SWPLD_PATH, PSU_PWR_REG);
/* Set the light of PSU */
if((power_state&0x80) != 0x80)
{
/* Red */
front_panel_led_value|=0x04;
dni_lock_cpld_write_attribute(SWPLD_PATH, LED_REG, front_panel_led_value);
}
else if((power_state&0x80)==0x80)
{
/* Green */
front_panel_led_value|=0x08;
dni_lock_cpld_write_attribute(SWPLD_PATH, LED_REG, front_panel_led_value);
}
else
dni_lock_cpld_write_attribute(SWPLD_PATH,LED_REG, front_panel_led_value);
break;
case LED_REAR_FAN_TRAY_1:
mux_info.channel= 0x00;
dev_info.addr = FAN_TRAY_1;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
rpm = dni_i2c_lock_read_attribute(NULL, FAN4_FRONT);
rpm1 = dni_i2c_lock_read_attribute(NULL, FAN4_REAR);
fan_tray_led_value &= ~0xC0;
if(fantray_present >= 0 && rpm != 960 && rpm != 0 && rpm1 != 960 && rpm1 != 0 )
{
/* Green */
fan_tray_led_value |=0x40;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
else
{
/* Red */
fan_tray_led_value |=0x80;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
break;
case LED_REAR_FAN_TRAY_2:
mux_info.channel= 0x01;
dev_info.addr = FAN_TRAY_2;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
rpm = dni_i2c_lock_read_attribute(NULL, FAN3_FRONT);
rpm1 = dni_i2c_lock_read_attribute(NULL, FAN3_REAR);
fan_tray_led_value &= ~0x30;
if(fantray_present >= 0 && rpm != 960 && rpm != 0 && rpm1 != 960 && rpm1 != 0 )
{
/* Green */
fan_tray_led_value |=0x10;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
else
{
/* Red */
fan_tray_led_value |=0x20;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
break;
case LED_REAR_FAN_TRAY_3:
mux_info.channel= 0x02;
dev_info.bus = I2C_BUS_3;
dev_info.addr = FAN_TRAY_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
rpm = dni_i2c_lock_read_attribute(NULL, FAN2_FRONT);
rpm1 = dni_i2c_lock_read_attribute(NULL, FAN2_REAR);
fan_tray_led_value &= ~0x0c;
if(fantray_present >= 0 && rpm != 960 && rpm != 0 && rpm1 != 960 && rpm1 != 0 )
{
/* Green */
fan_tray_led_value |=0x04;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
else
{
/* Red */
fan_tray_led_value |=0x08;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
break;
case LED_REAR_FAN_TRAY_4:
mux_info.channel= 0x03;
dev_info.addr = FAN_TRAY_4;
dev_info.bus = I2C_BUS_3;
fantray_present = dni_i2c_lock_read(&mux_info, &dev_info);
rpm = dni_i2c_lock_read_attribute(NULL, FAN1_FRONT);
rpm1 = dni_i2c_lock_read_attribute(NULL, FAN1_REAR);
fan_tray_led_value &= ~0x03;
if(fantray_present >= 0 && rpm != 960 && rpm != 0 && rpm1 != 960 && rpm1 != 0 )
{
/* Green */
fan_tray_led_value |=0x01;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
else
{
/* Red */
fan_tray_led_value |=0x02;
dni_lock_cpld_write_attribute(SWPLD_PATH,FAN_TRAY_LED_REG,fan_tray_led_value);
}
break;
}
return ONLP_STATUS_OK;
}
/*
* Generic LED ioctl interface.
*/
int
onlp_ledi_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
LIBRARY := x86_64_delta_agc7648a
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(BUILDER)/lib.mk

View File

@@ -0,0 +1,289 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <AIM/aim.h>
#include "platform_lib.h"
#include <onlplib/i2c.h>
#include <onlplib/mmap.h>
#include <pthread.h>
int dni_i2c_read_attribute_binary(char *filename, char *buffer, int buf_size, int data_len)
{
int fd;
int len;
if ((buffer == NULL) || (buf_size < 0)) {
return -1;
}
if ((fd = open(filename, O_RDONLY)) == -1) {
return -1;
}
if ((len = read(fd, buffer, buf_size)) < 0) {
close(fd);
return -1;
}
if ((close(fd) == -1)) {
return -1;
}
if ((len > buf_size) || (data_len != 0 && len != data_len)) {
return -1;
}
return 0;
}
int dni_i2c_read_attribute_string(char *filename, char *buffer, int buf_size, int data_len)
{
int ret;
if (data_len >= buf_size) {
return -1;
}
ret = dni_i2c_read_attribute_binary(filename, buffer, buf_size-1, data_len);
if (ret == 0) {
buffer[buf_size-1] = '\0';
}
return ret;
}
/* Lock function */
int dni_i2c_lock_read( mux_info_t * mux_info, dev_info_t * dev_info)
{
int r_data=0;
pthread_mutex_lock(&mutex);
if(mux_info != NULL)
{
char cpld_path[100] = {0};
sprintf(cpld_path, "%s/%d-%04x", SYS_DEV_PATH, mux_info->bus, mux_info->addr);
dni_lock_cpld_write_attribute(cpld_path, mux_info->offset, mux_info->channel);
}
if(dev_info->size == 1)
r_data = onlp_i2c_readb(dev_info->bus, dev_info->addr, dev_info->offset, dev_info->flags);
else
r_data = onlp_i2c_readw(dev_info->bus, dev_info->addr, dev_info->offset, dev_info->flags);
pthread_mutex_unlock(&mutex);
return r_data;
}
int dni_i2c_lock_write( mux_info_t * mux_info, dev_info_t * dev_info)
{
pthread_mutex_lock(&mutex);
if(mux_info != NULL)
{
char cpld_path[100] = {0};
sprintf(cpld_path, "%s/%d-%04x", SYS_DEV_PATH, mux_info->bus, mux_info->addr);
dni_lock_cpld_write_attribute(cpld_path, mux_info->offset, mux_info->channel);
}
/* Write size */
if(dev_info->size == 1)
onlp_i2c_write(dev_info->bus, dev_info->addr, dev_info->offset, 1, &dev_info->data_8, dev_info->flags);
else
onlp_i2c_writew(dev_info->bus, dev_info->addr, dev_info->offset, dev_info->data_16, dev_info->flags);
pthread_mutex_unlock(&mutex);
return 0;
}
int dni_i2c_lock_read_attribute(mux_info_t * mux_info, char * fullpath)
{
int fd, len, nbytes = 10;
char r_data[10] = {0};
pthread_mutex_lock(&mutex);
if(mux_info != NULL)
{
char cpld_path[100] = {0};
sprintf(cpld_path, "%s/%d-%04x", SYS_DEV_PATH, mux_info->bus, mux_info->addr);
dni_lock_cpld_write_attribute(cpld_path, mux_info->offset, mux_info->channel);
}
if ((fd = open(fullpath, O_RDONLY)) == -1)
{
goto ERR_HANDLE;
}
if ((len = read(fd, r_data, nbytes)) <= 0)
{
goto ERR_HANDLE;
}
close(fd);
pthread_mutex_unlock(&mutex);
return atoi(r_data);
ERR_HANDLE:
close(fd);
pthread_mutex_unlock(&mutex);
return -1;
}
int dni_i2c_lock_write_attribute(mux_info_t * mux_info, char * data, char * fullpath)
{
int fd, len, nbytes = 10;
pthread_mutex_lock(&mutex);
if(mux_info != NULL)
{
char cpld_path[100] = {0};
sprintf(cpld_path, "%s/%d-%04x", SYS_DEV_PATH, mux_info->bus, mux_info->addr);
dni_lock_cpld_write_attribute(cpld_path, mux_info->offset, mux_info->channel);
}
/* Create output file descriptor */
fd = open(fullpath, O_WRONLY, 0644);
if (fd == -1)
{
goto ERR_HANDLE;
}
len = write (fd, data, nbytes);
if (len != nbytes)
{
goto ERR_HANDLE;
}
close(fd);
pthread_mutex_unlock(&mutex);
return 0;
ERR_HANDLE:
close(fd);
pthread_mutex_unlock(&mutex);
return -1;
}
/* Use this function to select MUX and read data on CPLD */
int dni_lock_cpld_read_attribute(char *cpld_path, int addr)
{
int fd, len, nbytes = 10,data = 0;
char r_data[10] = {0};
char address[10] = {0};
char cpld_data_path[100] = {0};
char cpld_addr_path[100] = {0};
sprintf(cpld_data_path, "%s/data", cpld_path);
sprintf(cpld_addr_path, "%s/addr", cpld_path);
sprintf(address, "%02x", addr);
pthread_mutex_lock(&mutex1);
/* Create output file descriptor */
fd = open(cpld_addr_path, O_WRONLY, 0644);
if (fd == -1)
{
goto ERR_HANDLE;
}
len = write (fd, address, 2);
if (len <= 0)
{
goto ERR_HANDLE;
}
close(fd);
if ((fd = open(cpld_data_path, O_RDONLY)) == -1)
{
goto ERR_HANDLE;
}
if ((len = read(fd, r_data, nbytes)) <= 0)
{
goto ERR_HANDLE;
}
close(fd);
pthread_mutex_unlock(&mutex1);
sscanf(r_data, "%x", &data);
return data;
ERR_HANDLE:
close(fd);
pthread_mutex_unlock(&mutex1);
return -1;
}
/* Use this function to select MUX and write data on CPLD */
int dni_lock_cpld_write_attribute(char *cpld_path, int addr, int data)
{
int fd, len;
char address[10] = {0};
char cpld_data_path[100] = {0};
char cpld_addr_path[100] = {0};
sprintf(cpld_data_path, "%s/data", cpld_path);
sprintf(cpld_addr_path, "%s/addr", cpld_path);
sprintf(address, "%02x", addr);
pthread_mutex_lock(&mutex1);
/* Create output file descriptor */
fd = open(cpld_addr_path, O_WRONLY, 0644);
if (fd == -1)
{
goto ERR_HANDLE;
}
len = write(fd, address, 2);
if(len <= 0)
{
goto ERR_HANDLE;
}
close(fd);
fd = open(cpld_data_path, O_WRONLY, 0644);
if (fd == -1)
{
goto ERR_HANDLE;
}
sprintf(address, "%02x", data);
len = write (fd, address, 2);
if(len <= 0)
{
goto ERR_HANDLE;
}
close(fd);
pthread_mutex_unlock(&mutex1);
return 0;
ERR_HANDLE:
close(fd);
pthread_mutex_unlock(&mutex1);
return -1;
}

View File

@@ -0,0 +1,230 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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_delta_agc7648a_log.h"
#define CHASSIS_FAN_COUNT 8
#define CHASSIS_THERMAL_COUNT 8
#define PSU1_ID 1
#define PSU2_ID 2
#define SYS_DEV_PATH "/sys/bus/i2c/devices"
#define CPU_CPLD_PATH SYS_DEV_PATH "/2-0031"
#define SWPLD_PATH SYS_DEV_PATH "/5-0030"
#define SWPLD1_PATH SYS_DEV_PATH "/5-0031"
#define SWPLD2_PATH SYS_DEV_PATH "/5-0032"
#define PSU1_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/4-0058/"
#define PSU2_AC_PMBUS_PREFIX "/sys/bus/i2c/devices/4-0058/"
#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/35-0038/"
#define PSU2_AC_HWMON_PREFIX "/sys/bus/i2c/devices/36-003b/"
#define PSU1_AC_HWMON_NODE(node) PSU1_AC_HWMON_PREFIX#node
#define PSU2_AC_HWMON_NODE(node) PSU2_AC_HWMON_PREFIX#node
#define FAN1_FRONT "/sys/bus/i2c/devices/3-002c/fan1_input"
#define FAN1_REAR "/sys/bus/i2c/devices/3-002d/fan1_input"
#define FAN2_FRONT "/sys/bus/i2c/devices/3-002c/fan2_input"
#define FAN2_REAR "/sys/bus/i2c/devices/3-002d/fan2_input"
#define FAN3_FRONT "/sys/bus/i2c/devices/3-002c/fan3_input"
#define FAN3_REAR "/sys/bus/i2c/devices/3-002d/fan3_input"
#define FAN4_FRONT "/sys/bus/i2c/devices/3-002c/fan4_input"
#define FAN4_REAR "/sys/bus/i2c/devices/3-002d/fan4_input"
#define SFP_SELECT_PORT_PATH "/sys/bus/i2c/devices/8-0050/sfp_select_port"
#define SFP_IS_PRESENT_PATH "/sys/bus/i2c/devices/8-0050/sfp_is_present"
#define SFP_IS_PRESENT_ALL_PATH "/sys/bus/i2c/devices/8-0050/sfp_is_present_all"
#define SFP_EEPROM_PATH "/sys/bus/i2c/devices/8-0050/sfp_eeprom"
#define SFP_RESET_PATH "/sys/bus/i2c/devices/8-0050/sfp_reset"
#define SFP_LP_MODE_PATH "/sys/bus/i2c/devices/8-0050/sfp_lp_mode"
#define PSU_SEL_PATH "/sys/bus/i2c/devices/4-0058/psu_select_member"
#define IDPROM_PATH "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0053/eeprom"
/* I2C bus */
#define I2C_BUS_0 (0)
#define I2C_BUS_1 (1)
#define I2C_BUS_2 (2)
#define I2C_BUS_3 (3)
#define I2C_BUS_4 (4)
#define I2C_BUS_5 (5)
#define I2C_BUS_6 (6)
#define I2C_BUS_7 (7)
#define I2C_BUS_8 (8)
/* Device address */
#define SWPLD (0x30)
#define SWPLD1 (0x31)
#define SWPLD2 (0x32)
#define SWPLD2 (0x32)
#define FAN_IO_CTRL (0x27)
#define PSU_EEPROM (0x50)
#define EMC2305_FRONT_FAN (0x2C)
#define EMC2305_REAR_FAN (0x2D)
#define FAN_TRAY_LED_REG (0x65)
#define FAN_TRAY_1 (0x52)
#define FAN_TRAY_2 (0x53)
#define FAN_TRAY_3 (0x54)
#define FAN_TRAY_4 (0x55)
#define PORT_ADDR (0x50)
/* CPU CPLD Register */
#define SWPLD_VERSION_ADDR (0x01)
/* SWPLD(U21) Register */
#define QSFP_RESPOND_REG (0x64)
#define FAN_MUX_REG (0x67)
#define PSU_PRESENT_REG (0x0D)
#define PSU_PWR_REG (0x0B)
#define LED_REG (0x1C)
/* Not Yet classified */
#define PSU1_MUX_MASK (0x00)
#define PSU2_MUX_MASK (0x02)
#define CLOSE_RESPOND (0xFF)
#define PSU_FAN1 (0x00)
#define PSU_FAN2 (0x20)
#define FAN_DATA_HALF_SPEED (0x0032)
#define FAN_DATA_FULL_SPEED (0x0064)
#define FAN_DATA_STOP_D10_D3 (0xFF)
#define FAN_DATA_STOP_D2_D0 (0xE0)
#define TURN_OFF (0)
#define TURN_ON (1)
#define FAN_ZERO_TACH 960
#define MAX_REAR_FAN_SPEED 20500
#define MAX_FRONT_FAN_SPEED 23000
#define MAX_PSU_FAN_SPEED 19000
#define NUM_OF_THERMAL 8
#define NUM_OF_FAN_ON_MAIN_BROAD 8
#define NUM_OF_PSU_ON_MAIN_BROAD 2
#define NUM_OF_LED_ON_MAIN_BROAD 7
#define NUM_OF_CPLD 4
#define DEFAULT_FLAG (0x00)
#define NUM_OF_SFP 48
#define NUM_OF_QSFP 6
#define NUM_OF_PORT NUM_OF_SFP + NUM_OF_QSFP
int dni_i2c_read_attribute_binary(char *filename, char *buffer, int buf_size, int data_len);
int dni_i2c_read_attribute_string(char *filename, char *buffer, int buf_size, int data_len);
typedef struct dev_info_s
{
int bus;
int size;
uint8_t addr;
uint8_t data_8;
uint16_t data_16;
uint8_t offset;
uint32_t flags;
}dev_info_t;
typedef struct mux_info_s
{
int bus;
uint8_t addr;
uint8_t offset;
uint8_t channel;
char data[10];
char path[80];
uint32_t flags;
}mux_info_t;
pthread_mutex_t mutex;
pthread_mutex_t mutex1;
int dni_i2c_lock_read(mux_info_t * mux_info, dev_info_t * dev_info);
int dni_i2c_lock_write(mux_info_t * mux_info, dev_info_t * dev_info);
int dni_i2c_lock_read_attribute(mux_info_t * mux_info, char * fullpath);
int dni_i2c_lock_write_attribute(mux_info_t * mux_info, char *data, char * fullpath);
int dni_lock_cpld_read_attribute(char *cpld_path, int addr);
int dni_lock_cpld_write_attribute(char *cpld_path, int addr, int data);
int dni_psu_present_get(int index);
#define DEBUG_MODE 0
#if (DEBUG_MODE == 1)
#define DEBUG_PRINT(format, ...) printf(format, __VA_ARGS__)
#else
#define DEBUG_PRINT(format, ...)
#endif
typedef enum
{
THERMAL_RESERVED = 0,
THERMAL_CPU_CORE,
THERMAL_1_ON_CPU_BROAD,
THERMAL_2_ON_FAN_BROAD,
THERMAL_3_ON_MAIN_BROAD,
THERMAL_4_ON_MAIN_BROAD,
THERMAL_5_ON_MAIN_BROAD,
THERMAL_6_ON_MAIN_BROAD,
THERMAL_7_ON_MAIN_BROAD,
THERMAL_1_ON_PSU1,
THERMAL_1_ON_PSU2,
} onlp_thermal_id;
typedef enum
{
FAN_RESERVED = 0,
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
} onlp_fan_id;
typedef enum
{
LED_RESERVED = 0,
LED_FRONT_FAN,
LED_FRONT_SYS,
LED_FRONT_PWR,
LED_REAR_FAN_TRAY_1,
LED_REAR_FAN_TRAY_2,
LED_REAR_FAN_TRAY_3,
LED_REAR_FAN_TRAY_4
}onlp_led_id;
#endif /* __PLATFORM_LIB_H__ */

View File

@@ -0,0 +1,231 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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 <stdio.h>
#include <string.h>
#include "platform_lib.h"
#include <onlplib/i2c.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 VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_PSU(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
static int
dni_psu_pmbus_info_get(int id, char *node, int *value)
{
int ret = 0;
char buf[PSU_NODE_MAX_INT_LEN + 1] = {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 = dni_i2c_read_attribute_string(node_path, buf, sizeof(buf), 0);
if (ret == 0) {
*value = atoi(buf);
}
return ret;
}
int
onlp_psui_init(void)
{
return ONLP_STATUS_OK;
}
int
dni_psu_present_get(int index)
{
int state = 0;
uint8_t present_val;
present_val = dni_lock_cpld_read_attribute(SWPLD_PATH, PSU_PRESENT_REG);
if(index == 1) {
if((present_val & 0x01) == 0x00) {
state = 1;
} else {
state = 0;
}
} else {
if((present_val & 0x02) == 0x00) {
state = 1;
} else {
state = 0;
}
}
return state;
}
static int
dni_psu_info_get(onlp_psu_info_t* info)
{
int val = 0;
int index = ONLP_OID_ID_GET(info->hdr.id);
/* Set capability
*/
info->caps = ONLP_PSU_CAPS_AC;
if (info->status & ONLP_PSU_STATUS_FAILED) {
return ONLP_STATUS_OK;
}
/* 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);
char val_char[16] = { '\0' };
char node_path[PSU_NODE_MAX_PATH_LEN] = { '\0' };
sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, "psu_mfr_model");
dni_i2c_read_attribute_string(node_path, val_char, sizeof(val_char), 0);
strcpy(info->model, val_char);
sprintf(node_path, "%s%s", PSU1_AC_PMBUS_PREFIX, "psu_mfr_serial");
dni_i2c_read_attribute_string(node_path, val_char, sizeof(val_char), 0);
strcpy(info->serial, val_char);
/* Read voltage, current and power */
if (dni_psu_pmbus_info_get(index, "psu_v_out", &val) == 0) {
info->mvout = val;
info->caps |= ONLP_PSU_CAPS_VOUT;
}
if (dni_psu_pmbus_info_get(index, "psu_v_in", &val) == 0) {
info->mvin = val;
info->caps |= ONLP_PSU_CAPS_VIN;
}
if (dni_psu_pmbus_info_get(index, "psu_i_out", &val) == 0) {
info->miout = val;
info->caps |= ONLP_PSU_CAPS_IOUT;
}
if (dni_psu_pmbus_info_get(index, "psu_i_in", &val) == 0) {
info->miin = val;
info->caps |= ONLP_PSU_CAPS_IIN;
}
if (dni_psu_pmbus_info_get(index, "psu_p_out", &val) == 0) {
info->mpout = val;
info->caps |= ONLP_PSU_CAPS_POUT;
}
if (dni_psu_pmbus_info_get(index, "psu_p_in", &val) == 0) {
info->mpin = val;
info->caps |= ONLP_PSU_CAPS_PIN;
}
return ONLP_STATUS_OK;
}
/*
* Get all information about the given PSU oid.
*/
static onlp_psu_info_t pinfo[] =
{
{ }, /* Not used */
{
{ ONLP_PSU_ID_CREATE(PSU1_ID), "PSU-1", 0 },
},
{
{ ONLP_PSU_ID_CREATE(PSU2_ID), "PSU-2", 0 },
}
};
int
onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
{
int val, ret;
int index = ONLP_OID_ID_GET(id);
uint8_t power_good_val;
*info = pinfo[index]; /* Set the onlp_oid_hdr_t */
if(dni_psu_present_get(index) != 1) {
/* PSU(%d) present fail */
info->status |= ~ONLP_PSU_STATUS_PRESENT;
return ONLP_STATUS_OK;
} else {
info->status |= ONLP_PSU_STATUS_PRESENT;
}
/* Get power good status */
power_good_val = dni_lock_cpld_read_attribute(SWPLD_PATH, PSU_PWR_REG);
if(index == 1){
if((power_good_val & 0x80) == 0x80) {
val = PSU_STATUS_POWER_GOOD;
} else {
val = 0;
}
} else if(index == 2) {
if((power_good_val & 0x40) == 0x40) {
val = PSU_STATUS_POWER_GOOD;
} else {
val = 0;
}
}
if(val != PSU_STATUS_POWER_GOOD) {
/* Unable to read PSU(%d) node(psu_power_good) */
info->status |= ONLP_PSU_STATUS_UNPLUGGED;
}
/* select PSU(%d) module */
char index_data[2];
sprintf(index_data, "%d", index);
dni_i2c_lock_write_attribute(NULL, index_data, PSU_SEL_PATH);
ret = dni_psu_info_get(info);
return ret;
}
int
onlp_psui_ioctl(onlp_oid_t pid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,475 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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>
#include <fcntl.h> /* For O_RDWR && open */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <math.h>
#include <onlplib/i2c.h>
#include "platform_lib.h"
/******************* Utility Function *****************************************/
int
delta_agc7648a_get_respond_reg(int port)
{
if(port >= NUM_OF_SFP && port < (NUM_OF_SFP + NUM_OF_QSFP)){
return QSFP_RESPOND_REG;
}
else{
return -1;
}
}
int
delta_agc7648a_get_respond_val(int port)
{
if(port >= NUM_OF_SFP && port < (NUM_OF_SFP + NUM_OF_QSFP)){
return (port%8);
}
else{
return -1;
}
}
/******************************************************************************/
/************************************************************
*
* SFPI Entry Points
*
***********************************************************/
int
onlp_sfpi_init(void)
{
/* Called at initialization time */
return ONLP_STATUS_OK;
}
int
onlp_sfpi_bitmap_get(onlp_sfp_bitmap_t* bmap)
{
int p;
AIM_BITMAP_CLR_ALL(bmap);
for(p = 0; p < NUM_OF_PORT; p++) {
AIM_BITMAP_SET(bmap, p);
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_is_present(int port)
{
char port_data[2];
int present_val, present;
/* Select port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
/* Read sfp_is_present attribute of sfp module is presented or not */
present_val = dni_i2c_lock_read_attribute(NULL, SFP_IS_PRESENT_PATH);
/* From sfp_is_present value,
* return 0 = The module is preset
* return 1 = The module is NOT present
*/
if(present_val == 0) {
present = 1;
} else if (present_val == 1) {
present = 0;
AIM_LOG_ERROR("Unble to present status from port(%d)\r\n", port);
} else {
AIM_LOG_ERROR("Error to present status from port(%d)\r\n", port);
present = -1;
}
return present;
}
int
onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst)
{
char present_all_data[21] = {0};
uint32_t bytes[7];
/* Read presence bitmap from SWPLD QSFP28 Presence Register
* if only port 0 is present, return 7F FF FF FF
* if only port 0 and 1 present, return 3F FF FF FF
*/
if(dni_i2c_read_attribute_string(SFP_IS_PRESENT_ALL_PATH, present_all_data,
sizeof(present_all_data), 0) < 0) {
return -1;
}
int count = sscanf(present_all_data, "%x %x %x %x %x %x %x",
bytes+0,
bytes+1,
bytes+2,
bytes+3,
bytes+4,
bytes+5,
bytes+6
);
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;
}
/* Mask out non-existant QSFP ports */
bytes[6] &= 0x3F;
/* Convert to 64 bit integer in port order */
int i = 0;
uint64_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; i < NUM_OF_PORT; i++) {
AIM_BITMAP_MOD(dst, i, !(presence_all & 1));
presence_all >>= 1;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_eeprom_read(int port, uint8_t data[256])
{
char port_data[2];
int sfp_respond_reg, sfp_respond_val;
/* Get respond register if port have it */
sfp_respond_reg = delta_agc7648a_get_respond_reg(port);
if(sfp_respond_reg >= 0)
{
/* Set respond val */
sfp_respond_val = delta_agc7648a_get_respond_val(port);
dni_lock_cpld_write_attribute(SWPLD_PATH, sfp_respond_reg, sfp_respond_val);
}
/* Select port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
/* Read eeprom information into data[] */
if (dni_i2c_read_attribute_binary(SFP_EEPROM_PATH, (char *)data, 256, 256)
!= 0)
{
AIM_LOG_INFO("Unable to read eeprom from port(%d)\r\n", port);
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_dev_readb(int port, uint8_t devaddr, uint8_t addr)
{
char port_data[2];
int sfp_respond_reg, sfp_respond_val;
dev_info_t dev_info;
/* Get respond register if port have it */
sfp_respond_reg = delta_agc7648a_get_respond_reg(port);
if(sfp_respond_reg >= 0)
{
/* Set respond val */
sfp_respond_val = delta_agc7648a_get_respond_val(port);
dni_lock_cpld_write_attribute(SWPLD_PATH, sfp_respond_reg, sfp_respond_val);
}
/* Select port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
dev_info.bus = I2C_BUS_8;
dev_info.addr = PORT_ADDR;
dev_info.offset = addr;
dev_info.flags = ONLP_I2C_F_FORCE;
dev_info.size = 1; /* Read 1 byte */
return dni_i2c_lock_read(NULL, &dev_info);
}
int
onlp_sfpi_dev_writeb(int port, uint8_t devaddr, uint8_t addr, uint8_t value)
{
char port_data[2];
int sfp_respond_reg, sfp_respond_val;
dev_info_t dev_info;
/* Get respond register if port have it */
sfp_respond_reg = delta_agc7648a_get_respond_reg(port);
if(sfp_respond_reg >= 0)
{
/* Set respond val */
sfp_respond_val = delta_agc7648a_get_respond_val(port);
dni_lock_cpld_write_attribute(SWPLD_PATH, sfp_respond_reg, sfp_respond_val);
}
/* Select port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
dev_info.bus = I2C_BUS_8;
dev_info.addr = PORT_ADDR;
dev_info.offset = addr;
dev_info.flags = ONLP_I2C_F_FORCE;
dev_info.size = 1; /* Write 1 byte */
dev_info.data_8 = value;
return dni_i2c_lock_write(NULL, &dev_info);
}
int
onlp_sfpi_dev_readw(int port, uint8_t devaddr, uint8_t addr)
{
char port_data[2];
int sfp_respond_reg, sfp_respond_val;
dev_info_t dev_info;
/* Get respond register if port have it */
sfp_respond_reg = delta_agc7648a_get_respond_reg(port);
if(sfp_respond_reg >= 0)
{
/* Set respond val */
sfp_respond_val = delta_agc7648a_get_respond_val(port);
dni_lock_cpld_write_attribute(SWPLD_PATH, sfp_respond_reg, sfp_respond_val);
}
/* Select port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
dev_info.bus = I2C_BUS_8;
dev_info.addr = PORT_ADDR;
dev_info.offset = addr;
dev_info.flags = ONLP_I2C_F_FORCE;
dev_info.size = 2; /* Read 1 byte */
return dni_i2c_lock_read(NULL, &dev_info);
}
int
onlp_sfpi_dev_writew(int port, uint8_t devaddr, uint8_t addr, uint16_t value)
{
char port_data[2];
int sfp_respond_reg, sfp_respond_val;
dev_info_t dev_info;
/* Get respond register if port have it */
sfp_respond_reg = delta_agc7648a_get_respond_reg(port);
if(sfp_respond_reg >= 0)
{
/* Set respond val */
sfp_respond_val = delta_agc7648a_get_respond_val(port);
dni_lock_cpld_write_attribute(SWPLD_PATH, sfp_respond_reg, sfp_respond_val);
}
/* Select port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
dev_info.bus = I2C_BUS_8;
dev_info.addr = PORT_ADDR;
dev_info.offset = addr;
dev_info.flags = ONLP_I2C_F_FORCE;
dev_info.size = 2; /* Write 2 byte */
dev_info.data_16 = value;
return dni_i2c_lock_write(NULL, &dev_info);
}
int
onlp_sfpi_control_supported(int port, onlp_sfp_control_t control, int* rv)
{
char port_data[2];
/* Select QSFP port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
switch (control) {
case ONLP_SFP_CONTROL_RESET_STATE:
if(port >= NUM_OF_SFP && port < (NUM_OF_SFP + NUM_OF_QSFP)){
*rv = 1;
}
else{
*rv = 0;
}
break;
case ONLP_SFP_CONTROL_RX_LOS:
*rv = 0;
break;
case ONLP_SFP_CONTROL_TX_DISABLE:
*rv = 0;
break;
case ONLP_SFP_CONTROL_LP_MODE:
if(port >= NUM_OF_SFP && port < (NUM_OF_SFP + NUM_OF_QSFP)){
*rv = 1;
}
else{
*rv = 0;
}
break;
default:
break;
}
return ONLP_STATUS_OK;
}
int
onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value)
{
uint8_t value_t;
char port_data[2];
/* Select QSFP port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
switch (control) {
case ONLP_SFP_CONTROL_RESET_STATE:
sprintf(port_data, "%d", value);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_RESET_PATH);
value_t = ONLP_STATUS_OK;
break;
case ONLP_SFP_CONTROL_RX_LOS:
value_t = ONLP_STATUS_E_UNSUPPORTED;
break;
case ONLP_SFP_CONTROL_TX_DISABLE:
value_t = ONLP_STATUS_E_UNSUPPORTED;
break;
case ONLP_SFP_CONTROL_LP_MODE:
sprintf(port_data, "%d", value);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_LP_MODE_PATH);
value_t = ONLP_STATUS_OK;
break;
default:
value_t = ONLP_STATUS_E_UNSUPPORTED;
break;
}
return value_t;
}
int
onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value)
{
uint8_t value_t;
char port_data[2];
/* Select QSFP port */
sprintf(port_data, "%d", port + 1);
dni_i2c_lock_write_attribute(NULL, port_data, SFP_SELECT_PORT_PATH);
switch (control) {
case ONLP_SFP_CONTROL_RESET_STATE:
*value = dni_i2c_lock_read_attribute(NULL, SFP_RESET_PATH);
/* From sfp_reset value,
* return 0 = The module is in Reset
* return 1 = The module is NOT in Reset
*/
if (*value == 0){
*value = 1;
}
else if(*value == 1){
*value = 0;
}
value_t = ONLP_STATUS_OK;
break;
case ONLP_SFP_CONTROL_RX_LOS:
*value = 0;
value_t = ONLP_STATUS_E_UNSUPPORTED;
break;
case ONLP_SFP_CONTROL_TX_DISABLE:
*value = 0;
value_t = ONLP_STATUS_E_UNSUPPORTED;
break;
case ONLP_SFP_CONTROL_LP_MODE:
/* From sfp_lp_mode value,
* return 0 = The module is NOT in LP mode
* return 1 = The moduel is in LP mode
*/
*value = dni_i2c_lock_read_attribute(NULL, SFP_LP_MODE_PATH);
value_t = ONLP_STATUS_OK;
break;
default:
value_t = ONLP_STATUS_E_UNSUPPORTED;
break;
}
return value_t;
}
int
onlp_sfpi_denit(void)
{
return ONLP_STATUS_OK;
}
int
onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_sfpi_dom_read(int port, uint8_t data[256])
{
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_sfpi_post_insert(int port, sff_info_t* info)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
void
onlp_sfpi_debug(int port, aim_pvs_t* pvs)
{
}
int
onlp_sfpi_ioctl(int port, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,292 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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>
#include <onlplib/file.h>
#include <onlplib/i2c.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/thermali.h>
#include <onlp/platformi/fani.h>
#include <onlp/platformi/psui.h>
#include "x86_64_delta_agc7648a_int.h"
#include "x86_64_delta_agc7648a_log.h"
#include "platform_lib.h"
typedef struct cpld_dev_s{
char name[32];
char path[64];
}cpld_dev_t;
static cpld_dev_t cpld_dev[NUM_OF_CPLD] =
{
{"CPUCPLD" , CPU_CPLD_PATH},
{"SWPLD(U21)" , SWPLD_PATH },
{"SWPLD(U134)", SWPLD1_PATH },
{"SWPLD(U215)", SWPLD2_PATH }
};
/******************* Utility Function *****************************************/
int
decide_percentage(int *percentage, int temper)
{
int level;
if(temper <= 25)
{
*percentage = 40;
level = 0;
}
else if(temper > 25 && temper <= 40)
{
*percentage = 60;
level = 1;
}
else if(temper > 40 && temper <= 55)
{
*percentage = 80;
level = 2;
}
else if(temper > 55 && temper <= 75)
{
*percentage = 90;
level = 3;
}
else if(temper > 75)
{
*percentage = 100;
level = 4;
}
else
{
*percentage = 100;
level = 5;
}
return level;
}
/******************************************************************************/
const char*
onlp_sysi_platform_get(void)
{
return "x86-64-delta-agc7648a-r0";
}
int
onlp_sysi_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_sysi_onie_info_get(onlp_onie_info_t* onie)
{
onie->platform_name = aim_strdup("x86-64-delta_agc7648a-r0");
return ONLP_STATUS_OK;
}
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(*size == 256) {
*data = rdata;
return ONLP_STATUS_OK;
}
}
aim_free(rdata);
*size = 0;
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
{
char fullpath[128], buf[128], cpld_ver[256] = {0};
int i, v[NUM_OF_CPLD] = {0};
for(i = 0; i < NUM_OF_CPLD; ++i)
{
sprintf(fullpath, "%s/version", cpld_dev[i].path);
v[i] = dni_i2c_lock_read_attribute(NULL, fullpath);
sprintf(buf, "%s=%d ", cpld_dev[i].name, v[i]);
strcat(cpld_ver, buf);
}
pi->cpld_versions = aim_fstrdup("%s", cpld_ver);
return ONLP_STATUS_OK;
}
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)
{
int i;
onlp_oid_t* e = table;
memset(table, 0, max*sizeof(onlp_oid_t));
for (i = 1; i <= NUM_OF_THERMAL; i++)
{
*e++ = ONLP_THERMAL_ID_CREATE(i);
}
/* 4 LEDs on the chassis */
for (i = 1; i <= NUM_OF_LED_ON_MAIN_BROAD; i++)
{
*e++ = ONLP_LED_ID_CREATE(i);
}
/* 4 Fans on the chassis */
for (i = 1; i <= NUM_OF_FAN_ON_MAIN_BROAD; i++)
{
*e++ = ONLP_FAN_ID_CREATE(i);
}
/* 2 PSUs on the chassis */
for (i = 1; i <= NUM_OF_PSU_ON_MAIN_BROAD; i++)
{
*e++ = ONLP_PSU_ID_CREATE(i);
}
return 0;
}
int
onlp_sysi_platform_manage_fans(void)
{
int i, new_percentage, highest_temp = 0;
onlp_thermal_info_t thermal;
/* Get all thermal current temperature and decide fan percentage */
for(i = 1; i <= NUM_OF_THERMAL; ++i)
{
if(onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i), &thermal) != ONLP_STATUS_OK)
{
AIM_LOG_ERROR("Unable to read thermal status");
return ONLP_STATUS_E_INTERNAL;
}
thermal.mcelsius /= 1000;
if(thermal.mcelsius > highest_temp)
{
highest_temp = thermal.mcelsius;
}
decide_percentage(&new_percentage, highest_temp);
}
/* Set fantray RPM and PSU fan percentage */
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_1_ON_MAIN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_2_ON_MAIN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_3_ON_MAIN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_4_ON_MAIN_BOARD), MAX_FRONT_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_5_ON_MAIN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_6_ON_MAIN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_7_ON_MAIN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100);
onlp_fani_rpm_set(ONLP_FAN_ID_CREATE(FAN_8_ON_MAIN_BOARD), MAX_REAR_FAN_SPEED * new_percentage / 100);
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(FAN_1_ON_PSU1), new_percentage);
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(FAN_1_ON_PSU2), new_percentage);
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_leds(void)
{
uint8_t present_bit = 0 ,addr = 0;
/* set PWR led in front panel */
addr = dni_lock_cpld_read_attribute(SWPLD_PATH,LED_REG);
/* Turn the fan led on or off */
if((addr & 0x3) == 0 || (addr & 0x3) == 0x3 )
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_FRONT_FAN), TURN_OFF);
}
else
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_FRONT_FAN), TURN_ON);
}
if(dni_psu_present_get(1) == 1)
{ /* PSU1 is present */
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_FRONT_PWR), TURN_ON);
}
else
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_FRONT_PWR), TURN_OFF);
}
/* Rare light fan tray 1-4 */
present_bit = dni_lock_cpld_read_attribute(SWPLD_PATH,FAN_TRAY_LED_REG);
if ((present_bit& 0x08) == 0x00)
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_1), TURN_ON);
}
else
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_1), TURN_OFF);
}
if ((present_bit& 0x04) == 0x00)
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_2), TURN_ON);
}
else
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_2), TURN_OFF);
}
if ((present_bit& 0x02) == 0x00)
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_3), TURN_ON);
}
else
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_3), TURN_OFF);
}
if ((present_bit& 0x01) == 0x00)
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_4), TURN_ON);
}
else
{
onlp_ledi_set(ONLP_LED_ID_CREATE(LED_REAR_FAN_TRAY_4), TURN_OFF);
}
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,181 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
* Copyright (C) 2017 Delta Networks, Inc.
*
* 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.
*
***********************************************************/
#include <unistd.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include <onlp/platformi/thermali.h>
#include <fcntl.h>
#include "platform_lib.h"
#include <onlplib/i2c.h>
#define VALIDATE(_id) \
do { \
if(!ONLP_OID_IS_THERMAL(_id)) { \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
static char* last_path[] = /* must map with onlp_thermal_id */
{
"reserved",
NULL, /* CPU Core */
"2-004d/hwmon/hwmon3/temp1_input",
"3-004f/hwmon/hwmon4/temp1_input",
"6-004c/hwmon/hwmon6/temp1_input",
"6-004c/hwmon/hwmon6/temp2_input",
"6-004e/hwmon/hwmon5/temp1_input",
"6-004f/hwmon/hwmon7/temp1_input",
"7-004c/hwmon/hwmon8/temp1_input",
"4-0058/psu_temp1_input",
"4-0058/psu_temp1_input",
};
static char* cpu_coretemp_files[] =
{
"/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input",
"/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp3_input",
"/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp4_input",
"/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp5_input",
NULL,
};
/* Static values */
static onlp_thermal_info_t linfo[] = {
{ }, /* Not used */
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE), "CPU Core", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_1_ON_CPU_BROAD), "CPU below side thermal sensor (U57, Below of CPU)", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_2_ON_FAN_BROAD), "FAN board thermal sensor (U334)", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_3_ON_MAIN_BROAD), "MAC up side thermal sensor, local (U3, up side of MAC)", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_4_ON_MAIN_BROAD), "MAC up side thermal sensor, remote (U3, up side of MAC)", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_5_ON_MAIN_BROAD), "MAC down side thermal sensor (U24, down side of MAC)", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_6_ON_MAIN_BROAD), "MAC up side thermal sensor (U25, up side of MAC)", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_7_ON_MAIN_BROAD), "Thermal sensor on main board (U17)", 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
},
{ { 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
}
};
/*
* This will be called to intiialize the thermali subsystem.
*/
int
onlp_thermali_init(void)
{
return ONLP_STATUS_OK;
}
/*
* Retrieve the information structure for the given thermal OID.
*
* If the OID is invalid, return ONLP_E_STATUS_INVALID.
* If an unexpected error occurs, return ONLP_E_STATUS_INTERNAL.
* Otherwise, return ONLP_STATUS_OK with the OID's information.
*
* Note -- it is expected that you fill out the information
* structure even if the sensor described by the OID is not present.
*/
int
onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
{
int local_id, r_data;
char fullpath[256], psu_num[2];
mux_info_t mux_info;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
/* 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;
}
/* Configure attribute path of thermal */
sprintf(fullpath, "%s/%s", SYS_DEV_PATH, last_path[local_id]);
/* Configure MUX settings */
switch (local_id) {
case THERMAL_2_ON_FAN_BROAD:
mux_info.addr = SWPLD;
mux_info.flags = 0x00;
mux_info.bus = I2C_BUS_5;
mux_info.offset = FAN_MUX_REG;
mux_info.channel = 0x06;
break;
case THERMAL_1_ON_PSU1:
sprintf(psu_num, "%d", 1);
dni_i2c_lock_write_attribute(NULL, psu_num, PSU_SEL_PATH);
break;
case THERMAL_1_ON_PSU2:
sprintf(psu_num, "%d", 2);
dni_i2c_lock_write_attribute(NULL, psu_num, PSU_SEL_PATH);
break;
}
/* Read temperature into r_data */
if(local_id == THERMAL_2_ON_FAN_BROAD){
r_data = dni_i2c_lock_read_attribute(&mux_info, fullpath);
}else{
r_data = dni_i2c_lock_read_attribute(NULL, fullpath);
}
info->mcelsius = r_data;
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,81 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
/* <auto.start.cdefs(X86_64_DELTA_AGC7648A_CONFIGHEADER).source> */
#define __x86_64_delta_agc7648a_config_STRINGIFY_NAME(_x) #_x
#define __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(_x) __x86_64_delta_agc7648a_config_STRINGIFY_NAME(_x)
x86_64_delta_agc7648a_config_settings_t x86_64_delta_agc7648a_config_settings[] =
{
#ifdef X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGINCLUDE_LOGGING(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGPORTING_STDLIB(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGPORTING_INCLUDE_STDLIB_HEADERS(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION
{ __x86_64_delta_agc7648a_config_STRINGIFY_NAME(X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION), __x86_64_delta_agc7648a_config_STRINGIFY_VALUE(X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION) },
#else
{ X86_64_DELTA_AGC7648A_CONFIGINCLUDE_DEFAULT_FAN_DIRECTION(__x86_64_delta_agc7648a_config_STRINGIFY_NAME), "__undefined__" },
#endif
{ NULL, NULL }
};
#undef __x86_64_delta_agc7648a_config_STRINGIFY_VALUE
#undef __x86_64_delta_agc7648a_config_STRINGIFY_NAME
const char*
x86_64_delta_agc7648a_config_lookup(const char* setting)
{
int i;
for(i = 0; x86_64_delta_agc7648a_config_settings[i].name; i++) {
if(strcmp(x86_64_delta_agc7648a_config_settings[i].name, setting)) {
return x86_64_delta_agc7648a_config_settings[i].value;
}
}
return NULL;
}
int
x86_64_delta_agc7648a_config_show(struct aim_pvs_s* pvs)
{
int i;
for(i = 0; x86_64_delta_agc7648a_config_settings[i].name; i++) {
aim_printf(pvs, "%s = %s\n", x86_64_delta_agc7648a_config_settings[i].name, x86_64_delta_agc7648a_config_settings[i].value);
}
return i;
}
/* <auto.end.cdefs(X86_64_DELTA_AGC7648A_CONFIGHEADER).source> */

View File

@@ -0,0 +1,10 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
/* <--auto.start.enum(ALL).source> */
/* <auto.end.enum(ALL).source> */

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
* x86_64_delta_agc7648a Internal Header
*
*****************************************************************************/
#ifndef __x86_64_delta_agc7648a_INT_H__
#define __x86_64_delta_agc7648a_INT_H__
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
#endif /* __x86_64_delta_agc7648a_INT_H__ */

View File

@@ -0,0 +1,18 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
#include "x86_64_delta_agc7648a_log.h"
/*
* x86_64_delta_agc7648a log struct.
*/
AIM_LOG_STRUCT_DEFINE(
X86_64_DELTA_AGC7648A_CONFIGLOG_OPTIONS_DEFAULT,
X86_64_DELTA_AGC7648A_CONFIGLOG_BITS_DEFAULT,
NULL, /* Custom log map */
X86_64_DELTA_AGC7648A_CONFIGLOG_CUSTOM_BITS_DEFAULT
);

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#ifndef __x86_64_delta_agc7648a_LOG_H__
#define __x86_64_delta_agc7648a_LOG_H__
#define AIM_LOG_MODULE_NAME x86_64_delta_agc7648a
#include <AIM/aim_log.h>
#endif /* __x86_64_delta_agc7648a_LOG_H__ */

View File

@@ -0,0 +1,24 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
#include "x86_64_delta_agc7648a_log.h"
static int
datatypes_init__(void)
{
#define x86_64_delta_agc7648a_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL);
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a.x>
return 0;
}
void __x86_64_delta_agc7648a_module_init__(void)
{
AIM_LOG_STRUCT_REGISTER();
datatypes_init__();
}
int __onlp_platform_version__ = 1;

View File

@@ -0,0 +1,50 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_agc7648a/x86_64_delta_agc7648a_config.h>
#if X86_64_DELTA_AGC7648A_CONFIGINCLUDE_UCLI == 1
#include <uCli/ucli.h>
#include <uCli/ucli_argparse.h>
#include <uCli/ucli_handler_macros.h>
static ucli_status_t
x86_64_delta_agc7648a_ucli_ucli__config__(ucli_context_t* uc)
{
UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_delta_agc7648a)
}
/* <auto.ucli.handlers.start> */
/* <auto.ucli.handlers.end> */
static ucli_module_t
x86_64_delta_agc7648a_ucli_module__ =
{
"x86_64_delta_agc7648a_ucli",
NULL,
x86_64_delta_agc7648a_ucli_ucli_handlers__,
NULL,
NULL,
};
ucli_node_t*
x86_64_delta_agc7648a_ucli_node_create(void)
{
ucli_node_t* n;
ucli_module_init(&x86_64_delta_agc7648a_ucli_module__);
n = ucli_node_create("x86_64_delta_agc7648a", NULL, &x86_64_delta_agc7648a_ucli_module__);
ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_delta_agc7648a"));
return n;
}
#else
void*
x86_64_delta_agc7648a_ucli_node_create(void)
{
return NULL;
}
#endif

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=delta BASENAME=x86-64-delta-agc7648a REVISION=r0

View File

@@ -0,0 +1,30 @@
---
######################################################################
#
# platform-config for AGC7648A
#
######################################################################
x86-64-delta-agc7648a-r0:
grub:
serial: >-
--port=0x3f8
--speed=115200
--word=8
--parity=no
--stop=1
kernel:
<<: *kernel-3-16
args: >-
nopat
console=ttyS0,115200n8
##network
## interfaces:
## ma1:
## name: ~
## syspath: pci0000:00/0000:00:14.0

View File

@@ -0,0 +1,55 @@
from onl.platform.base import *
from onl.platform.delta import *
class OnlPlatform_x86_64_delta_agc7648a_r0(OnlPlatformDelta,
OnlPlatformPortConfig_32x100):
PLATFORM='x86-64-delta-agc7648a-r0'
MODEL="AGC7648A"
SYS_OBJECT_ID=".7648"
def baseconfig(self):
# Insert kernel module
self.insmod('i2c_cpld')
self.insmod('agc7648a_emc2305')
self.insmod('agc7648a_dps800ab')
self.insmod('agc7648a_sfp')
# Register multuplexer
self.new_i2c_device('pca9547', 0x71, 1)
# Register cpld
self.new_i2c_device('cpld', 0x31, 2)
self.new_i2c_device('cpld', 0x30, 5)
self.new_i2c_device('cpld', 0x31, 5)
self.new_i2c_device('cpld', 0x32, 5)
# Register eeprom
self.new_i2c_device('24c02', 0x53, 2)
# Register fan control
os.system("echo 0x67 > /sys/bus/i2c/devices/5-0030/addr")
os.system("echo 0x05 > /sys/bus/i2c/devices/5-0030/data")
self.new_i2c_device('agc7648a_emc2305', 0x2c, 3)
self.new_i2c_device('agc7648a_emc2305', 0x2d, 3)
# Register thermal
self.new_i2c_device('tmp75', 0x4d, 2)
os.system("echo 0x06 > /sys/bus/i2c/devices/5-0030/data")
self.new_i2c_device('tmp75', 0x4f, 3)
self.new_i2c_device('tmp75', 0x4e, 6)
self.new_i2c_device('adt7461', 0x4c, 6)
self.new_i2c_device('tmp75', 0x4f, 6)
self.new_i2c_device('tmp423', 0x4c, 7)
# Register PSU
os.system("echo 0x1f > /sys/bus/i2c/devices/5-0030/addr")
os.system("echo 0x00 > /sys/bus/i2c/devices/5-0030/data")
self.new_i2c_device('agc7648a_dps800ab', 0x58, 4)
# Register SFP
self.new_i2c_device('agc7648a_sfp', 0x50, 8)
# Set front panel green light of sys led
os.system("echo 0x30 > /sys/bus/i2c/devices/5-0030/addr")
os.system("echo 0x10 > /sys/bus/i2c/devices/5-0030/data")
return True

View File

@@ -0,0 +1,3 @@
*x86*64*delta*wb2448.mk
onlpdump.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/no-platform-modules.yml ARCH=amd64 VENDOR=delta BASENAME=x86-64-delta-wb2448

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-delta-wb2448 ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu

View File

@@ -0,0 +1,2 @@
FILTER=src
include $(ONL)/make/subdirs.mk

View File

@@ -0,0 +1,45 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# 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 $(ONL)/make/config.amd64.mk
MODULE := libonlp-x86-64-delta-wb2448
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF x86_64_delta_wb2448 onlplib
DEPENDMODULE_HEADERS := sff
include $(BUILDER)/dependmodules.mk
SHAREDLIB := libonlp-x86-64-delta-wb2448.so
$(SHAREDLIB)_TARGETS := $(ALL_TARGETS)
include $(BUILDER)/so.mk
.DEFAULT_GOAL := $(SHAREDLIB)
GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -fPIC
GLOBAL_LINK_LIBS += -lpthread
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the libonlp-x86-64-delta-wb2448-r0 module.
#
# Autogenerated 2016-03-16 22:11:47.698846
#
###############################################################################
libonlp-x86-64-delta-wb2448-r0_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1,46 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# 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 $(ONL)/make/config.amd64.mk
.DEFAULT_GOAL := onlpdump
MODULE := onlpdump
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF onlp x86_64_delta_wb2448 onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS
include $(BUILDER)/dependmodules.mk
BINARY := onlpdump
$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS)
include $(BUILDER)/bin.mk
GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1
GLOBAL_LINK_LIBS += -lpthread -lm
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1 @@
name: x86_64_delta_wb2448

View File

@@ -0,0 +1,10 @@
############################################################
#
#
#
############################################################
include $(ONL)/make/config.mk
MODULE := x86_64_delta_wb2448
AUTOMODULE := x86_64_delta_wb2448
include $(BUILDER)/definemodule.mk

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# x86_64_delta_wb2448 Autogeneration
#
###############################################################################
x86_64_delta_wb2448_AUTO_DEFS := module/auto/x86_64_delta_wb2448.yml
x86_64_delta_wb2448_AUTO_DIRS := module/inc/x86_64_delta_wb2448 module/src
include $(BUILDER)/auto.mk

View File

@@ -0,0 +1,55 @@
###############################################################################
#
# x86_64_delta_wb2448 Autogeneration Definitions.
#
###############################################################################
cdefs: &cdefs
- X86_64_DELTA_WB2448_CONFIG_INCLUDE_LOGGING:
doc: "Include or exclude logging."
default: 1
- X86_64_DELTA_WB2448_CONFIG_LOG_OPTIONS_DEFAULT:
doc: "Default enabled log options."
default: AIM_LOG_OPTIONS_DEFAULT
- X86_64_DELTA_WB2448_CONFIG_LOG_BITS_DEFAULT:
doc: "Default enabled log bits."
default: AIM_LOG_BITS_DEFAULT
- X86_64_DELTA_WB2448_CONFIG_LOG_CUSTOM_BITS_DEFAULT:
doc: "Default enabled custom log bits."
default: 0
- X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB:
doc: "Default all porting macros to use the C standard libraries."
default: 1
- X86_64_DELTA_WB2448_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS:
doc: "Include standard library headers for stdlib porting macros."
default: X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB
- X86_64_DELTA_WB2448_CONFIG_INCLUDE_UCLI:
doc: "Include generic uCli support."
default: 0
- X86_64_DELTA_WB2448_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION:
doc: "Assume chassis fan direction is the same as the PSU fan direction."
default: 0
- X86_64_DELTA_WB2448_CONFIG_SFP_COUNT:
doc: "SFP port numbers."
default: 4
- X86_64_DELTA_WB2448_CONFIG_FAN_RPM_MAX:
doc: "Max fan speed."
default: 18000
definitions:
cdefs:
X86_64_DELTA_WB2448_CONFIG_HEADER:
defs: *cdefs
basename: x86_64_delta_wb2448_config
portingmacro:
X86_64_DELTA_WB2448:
macros:
- malloc
- free
- memset
- memcpy
- strncpy
- vsnprintf
- snprintf
- strlen

View File

@@ -0,0 +1,16 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_delta_wb2448/x86_64_delta_wb2448_config.h>
/* <--auto.start.xmacro(ALL).define> */
/* <auto.end.xmacro(ALL).define> */
/* <--auto.start.xenum(ALL).define> */
/* <auto.end.xenum(ALL).define> */

View File

@@ -0,0 +1,155 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_wb2448 Configuration Header
*
* @addtogroup x86_64_delta_wb2448-config
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_WB2448_CONFIG_H__
#define __X86_64_DELTA_WB2448_CONFIG_H__
#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG
#include <global_custom_config.h>
#endif
#ifdef X86_64_DELTA_WB2448_INCLUDE_CUSTOM_CONFIG
#include <x86_64_delta_wb2448_custom_config.h>
#endif
/* <auto.start.cdefs(x86_64_delta_wb2448_CONFIG_HEADER).header> */
#include <AIM/aim.h>
/**
* X86_64_DELTA_WB2448_CONFIG_INCLUDE_LOGGING
*
* Include or exclude logging. */
#ifndef X86_64_DELTA_WB2448_CONFIG_INCLUDE_LOGGING
#define X86_64_DELTA_WB2448_CONFIG_INCLUDE_LOGGING 1
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_LOG_OPTIONS_DEFAULT
*
* Default enabled log options. */
#ifndef X86_64_DELTA_WB2448_CONFIG_LOG_OPTIONS_DEFAULT
#define X86_64_DELTA_WB2448_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_LOG_BITS_DEFAULT
*
* Default enabled log bits. */
#ifndef X86_64_DELTA_WB2448_CONFIG_LOG_BITS_DEFAULT
#define X86_64_DELTA_WB2448_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_LOG_CUSTOM_BITS_DEFAULT
*
* Default enabled custom log bits. */
#ifndef X86_64_DELTA_WB2448_CONFIG_LOG_CUSTOM_BITS_DEFAULT
#define X86_64_DELTA_WB2448_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB
*
* Default all porting macros to use the C standard libraries. */
#ifndef X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB
#define X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB 1
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
*
* Include standard library headers for stdlib porting macros. */
#ifndef X86_64_DELTA_WB2448_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
#define X86_64_DELTA_WB2448_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_INCLUDE_UCLI
*
* Include generic uCli support. */
#ifndef X86_64_DELTA_WB2448_CONFIG_INCLUDE_UCLI
#define X86_64_DELTA_WB2448_CONFIG_INCLUDE_UCLI 0
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
*
* Assume chassis fan direction is the same as the PSU fan direction. */
#ifndef X86_64_DELTA_WB2448_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
#define X86_64_DELTA_WB2448_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION 0
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_SFP_COUNT
*
* SFP port numbers. */
#ifndef X86_64_DELTA_WB2448_CONFIG_SFP_COUNT
#define X86_64_DELTA_WB2448_CONFIG_SFP_COUNT 4
#endif
/**
* X86_64_DELTA_WB2448_CONFIG_FAN_RPM_MAX
*
* Max fan speed. */
#ifndef X86_64_DELTA_WB2448_CONFIG_FAN_RPM_MAX
#define X86_64_DELTA_WB2448_CONFIG_FAN_RPM_MAX 18000
#endif
/**
* All compile time options can be queried or displayed
*/
/** Configuration settings structure. */
typedef struct x86_64_delta_wb2448_config_settings_s {
/** name */
const char* name;
/** value */
const char* value;
} x86_64_delta_wb2448_config_settings_t;
/** Configuration settings table. */
/** x86_64_delta_wb2448_config_settings table. */
extern x86_64_delta_wb2448_config_settings_t x86_64_delta_wb2448_config_settings[];
/**
* @brief Lookup a configuration setting.
* @param setting The name of the configuration option to lookup.
*/
const char* x86_64_delta_wb2448_config_lookup(const char* setting);
/**
* @brief Show the compile-time configuration.
* @param pvs The output stream.
*/
int x86_64_delta_wb2448_config_show(struct aim_pvs_s* pvs);
/* <auto.end.cdefs(x86_64_delta_wb2448_CONFIG_HEADER).header> */
#include "x86_64_delta_wb2448_porting.h"
#endif /* __x86_64_delta_wb2448_CONFIG_H__ */
/* @} */

View File

@@ -0,0 +1,26 @@
/**************************************************************************//**
*
* x86_64_delta_wb2448 Doxygen Header
*
*****************************************************************************/
#ifndef __X86_64_DELTA_WB2448_DOX_H__
#define _X86_64_DELTA_WB2448_DOX_H__
/**
* @defgroup x86_64_delta_wb2448 x86_64_delta_wb2448 - x86_64_delta_wb2448 Description
*
The documentation overview for this module should go here.
*
* @{
*
* @defgroup x86_64_delta_wb2448-x86_64_delta_wb2448 Public Interface
* @defgroup x86_64_delta_wb2448-config Compile Time Configuration
* @defgroup x86_64_delta_wb2448-porting Porting Macros
*
* @}
*
*/
#endif /* __X86_64_DELTA_WB2448_DOX_H__ */

View File

@@ -0,0 +1,107 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_delta_wb2448 Porting Macros.
*
* @addtogroup x86_64_delta_wb2448-porting
* @{
*
*****************************************************************************/
#ifndef __X86_64_DELTA_WB2448_PORTING_H__
#define __X86_64_DELTA_WB2448_PORTING_H__
/* <auto.start.portingmacro(ALL).define> */
#if X86_64_DELTA_WB2448_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <memory.h>
#endif
#ifndef X86_64_DELTA_WB2448_MALLOC
#if defined(GLOBAL_MALLOC)
#define X86_64_DELTA_WB2448_MALLOC GLOBAL_MALLOC
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_MALLOC malloc
#else
#error The macro X86_64_DELTA_WB2448_MALLOC is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_FREE
#if defined(GLOBAL_FREE)
#define X86_64_DELTA_WB2448_FREE GLOBAL_FREE
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_FREE free
#else
#error The macro X86_64_DELTA_WB2448_FREE is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_MEMSET
#if defined(GLOBAL_MEMSET)
#define X86_64_DELTA_WB2448_MEMSET GLOBAL_MEMSET
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_MEMSET memset
#else
#error The macro X86_64_DELTA_WB2448_MEMSET is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_MEMCPY
#if defined(GLOBAL_MEMCPY)
#define X86_64_DELTA_WB2448_MEMCPY GLOBAL_MEMCPY
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_MEMCPY memcpy
#else
#error The macro X86_64_DELTA_WB2448_MEMCPY is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_STRNCPY
#if defined(GLOBAL_STRNCPY)
#define X86_64_DELTA_WB2448_STRNCPY GLOBAL_STRNCPY
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_STRNCPY strncpy
#else
#error The macro X86_64_DELTA_WB2448_STRNCPY is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_VSNPRINTF
#if defined(GLOBAL_VSNPRINTF)
#define X86_64_DELTA_WB2448_VSNPRINTF GLOBAL_VSNPRINTF
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_VSNPRINTF vsnprintf
#else
#error The macro X86_64_DELTA_WB2448_VSNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_SNPRINTF
#if defined(GLOBAL_SNPRINTF)
#define X86_64_DELTA_WB2448_SNPRINTF GLOBAL_SNPRINTF
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_SNPRINTF snprintf
#else
#error The macro X86_64_DELTA_WB2448_SNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef X86_64_DELTA_WB2448_STRLEN
#if defined(GLOBAL_STRLEN)
#define X86_64_DELTA_WB2448_STRLEN GLOBAL_STRLEN
#elif X86_64_DELTA_WB2448_CONFIG_PORTING_STDLIB == 1
#define X86_64_DELTA_WB2448_STRLEN strlen
#else
#error The macro X86_64_DELTA_WB2448_STRLEN is required but cannot be defined.
#endif
#endif
/* <auto.end.portingmacro(ALL).define> */
#endif /* __X86_64_DELTA_WB2448_PORTING_H__ */
/* @} */

View File

@@ -0,0 +1,10 @@
###############################################################################
#
#
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_delta_wb2448_INCLUDES := -I $(THIS_DIR)inc
x86_64_delta_wb2448_INTERNAL_INCLUDES := -I $(THIS_DIR)src
x86_64_delta_wb2448_DEPENDMODULE_ENTRIES := init:x86_64_delta_wb2448 ucli:x86_64_delta_wb2448

View File

@@ -0,0 +1,12 @@
###############################################################################
#
# Local source generation targets.
#
###############################################################################
include ../../../../init.mk
ucli:
$(SUBMODULE_BIGCODE)/tools/uclihandlers.py x86_64_delta_wb2448_ucli.c

View File

@@ -0,0 +1,154 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc.
*
* 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 <onlp/platformi/fani.h>
#include "x86_64_delta_wb2448_int.h"
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <onlplib/mmap.h>
#include "platform_lib.h"
#define VALIDATE(_id) \
do \
{ \
if(!ONLP_OID_IS_FAN(_id)) \
{ \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
enum onlp_fan_id
{
FAN_RESERVED = 0,
SYSTEM_FAN_1,
SYSTEM_FAN_2,
};
/* Static values */
static onlp_fan_info_t linfo[] =
{
{ }, /* Not used */
{
{ ONLP_FAN_ID_CREATE(SYSTEM_FAN_1), "Chassis System FAN 1", 0},
ONLP_FAN_STATUS_PRESENT,
ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE, 0, 0, ONLP_FAN_MODE_INVALID,
},
{
{ ONLP_FAN_ID_CREATE(SYSTEM_FAN_2), "Chassis System FAN 2", 0},
ONLP_FAN_STATUS_PRESENT,
ONLP_FAN_CAPS_SET_PERCENTAGE | ONLP_FAN_CAPS_GET_RPM | ONLP_FAN_CAPS_GET_PERCENTAGE, 0, 0, ONLP_FAN_MODE_INVALID,
},
};
/*
* This function will be called prior to all of onlp_fani_* functions.
*/
int
onlp_fani_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
{
INT4 rv = ONLP_STATUS_OK;
INT4 local_id = 0;
UINT4 u4Data = 0;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
*info = linfo[ONLP_OID_ID_GET(id)];
switch(local_id)
{
case SYSTEM_FAN_1:
rv = ifnBmcFanSpeedGet("FanPWM_1", &u4Data);
break;
case SYSTEM_FAN_2:
rv = ifnBmcFanSpeedGet("FanPWM_2", &u4Data);
break;
default:
AIM_LOG_ERROR("Invalid Fan ID!!\n");
rv = ONLP_STATUS_E_PARAM;
}
if(rv == ONLP_STATUS_OK)
{
info->rpm = u4Data;
info->percentage = (info->rpm * 100) / X86_64_DELTA_WB2448_CONFIG_FAN_RPM_MAX;
}
return rv;
}
int
onlp_fani_percentage_set(onlp_oid_t id, int p)
{
INT4 local_id;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
if ( p < 0 || p > 100)
{
AIM_LOG_ERROR("Invalid fan percentage !!");
return ONLP_STATUS_E_PARAM;
}
if (ifnBmcFanSpeedSet(local_id - 1, p) != ONLP_STATUS_OK)
{
return ONLP_STATUS_E_INTERNAL;
}
return ONLP_STATUS_OK;
}
int
onlp_fani_rpm_set(onlp_oid_t id, int rpm)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_fani_mode_set(onlp_oid_t id, onlp_fan_mode_t mode)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_fani_ioctl(onlp_oid_t fid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

View File

@@ -0,0 +1,289 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc.
*
* 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 "x86_64_delta_wb2448_int.h"
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <onlplib/mmap.h>
#include "platform_lib.h"
#define VALIDATE(_id) \
do \
{ \
if(!ONLP_OID_IS_LED(_id)) \
{ \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
#define I2C_BUS 0x04
#define CPLD_ADDR 0x28
#define SYS_LED_REGISTER 0x09
#define TEMP_LED_REGISTER 0x09
#define FAN_LED_REGISTER 0x09
#define LED_ADDR_LEN 0x01
#define LED_DATA_LEN 0x01
/* LED related data
*/
enum onlp_led_id
{
LED_RESERVED = 0,
LED_SYSTEM,
LED_FAN,
LED_TEMP
};
enum led_light_mode
{
LED_MODE_OFF = 0,
LED_MODE_GREEN,
LED_MODE_RED,
LED_MODE_AMBER,
LED_MODE_BLUE,
LED_MODE_GREEN_BLINK =0 ,
LED_MODE_AMBER_BLINK,
LED_MODE_RED_BLINK = 3,
LED_MODE_BLUE_BLINK,
LED_MODE_AUTO,
LED_MODE_UNKNOWN
};
typedef struct led_light_mode_map
{
enum onlp_led_id id;
enum led_light_mode driver_led_mode;
enum onlp_led_mode_e onlp_led_mode;
} led_light_mode_map_t;
led_light_mode_map_t led_map[] =
{
{LED_SYSTEM, LED_MODE_GREEN_BLINK, ONLP_LED_MODE_GREEN_BLINKING},
{LED_SYSTEM, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_SYSTEM, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_SYSTEM, LED_MODE_RED_BLINK, ONLP_LED_MODE_RED_BLINKING},
{LED_FAN, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_FAN, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_TEMP, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_TEMP, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_TEMP, LED_MODE_RED, ONLP_LED_MODE_RED}
};
/*
* Get the information for the given LED OID.
*/
static onlp_led_info_t linfo[] =
{
{ },
{
{ ONLP_LED_ID_CREATE(LED_SYSTEM), "Chassis LED 1 (SYSTEM)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_GREEN_BLINKING | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED | ONLP_LED_CAPS_RED_BLINKING,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN), "Chassis LED 2 (FAN)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
},
{
{ ONLP_LED_ID_CREATE(LED_TEMP), "Chassis LED 3 (TEMP)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_RED,
},
};
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]);
for(i = 0; i < nsize; i++)
{
if (id == led_map[i].id && onlp_led_mode == led_map[i].onlp_led_mode)
{
return led_map[i].driver_led_mode;
}
}
return 0;
}
int
onlp_ledi_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
{
INT4 rv = ONLP_STATUS_OK;
INT4 local_id = 0;
UINT4 u4LedMode = 0;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
*info = linfo[ONLP_OID_ID_GET(id)];
/* Get LED mode */
switch(local_id)
{
case LED_SYSTEM:
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, SYS_LED_REGISTER, LED_ADDR_LEN, &u4LedMode, LED_DATA_LEN);
u4LedMode = u4LedMode >> 6;
break;
case LED_FAN:
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, TEMP_LED_REGISTER, LED_ADDR_LEN, &u4LedMode, LED_DATA_LEN);
u4LedMode = (u4LedMode >> 2) & 0x03;
break;
case LED_TEMP:
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, FAN_LED_REGISTER, LED_ADDR_LEN, &u4LedMode, LED_DATA_LEN);
u4LedMode = (u4LedMode >> 4) & 0x03;
break;
default:
AIM_LOG_ERROR("Invalid LED ID!!\n");
rv = ONLP_STATUS_E_PARAM;
}
if( rv == ONLP_STATUS_OK)
{
info->mode = driver_to_onlp_led_mode(local_id, u4LedMode);
/* Set the on/off status */
if (info->mode != ONLP_LED_MODE_OFF)
{
info->status |= ONLP_LED_STATUS_ON;
}
}
return rv;
}
/*
* @brief Turn an LED on or off.
* @param id The LED OID
* @param on_or_off Led on (1) or LED off (0)
* @param Relevant if the LED has the ON_OFF capability.
* @note For the purposes of this function the
* interpretation of "on" for multi-mode or multi-color LEDs
* is up to the platform implementation.
*/
int
onlp_ledi_set(onlp_oid_t id, int on_or_off)
{
VALIDATE(id);
if (!on_or_off)
{
return onlp_ledi_mode_set(id, ONLP_LED_MODE_OFF);
}
return ONLP_STATUS_E_UNSUPPORTED;
}
int
onlp_ledi_ioctl(onlp_oid_t id, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}
/*
* This function puts the LED into the given mode. It is a more functional
* interface for multimode LEDs.
*
* Only modes reported in the LED's capabilities will be attempted.
*/
int
onlp_ledi_mode_set(onlp_oid_t id, onlp_led_mode_t mode)
{
INT4 rv = ONLP_STATUS_OK;
INT4 local_id = 0;
UINT4 u4Addr = 0;
UINT4 u4NewLedMode = 0;
UINT4 u4OldLedMode = 0;
onlp_led_mode_t driver_led_mode = 0;
VALIDATE(id);
local_id = ONLP_OID_ID_GET(id);
driver_led_mode = onlp_to_driver_led_mode(local_id, mode);
switch(local_id)
{
case LED_SYSTEM:
u4Addr = SYS_LED_REGISTER;
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, u4Addr, LED_ADDR_LEN, &u4OldLedMode, LED_DATA_LEN);
u4NewLedMode = ( (u4OldLedMode & 0x3C) | ((driver_led_mode << 6) & 0xC0) );
break;
case LED_FAN:
u4Addr = FAN_LED_REGISTER;
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, u4Addr, LED_ADDR_LEN, &u4OldLedMode, LED_DATA_LEN);
u4NewLedMode = ( (u4OldLedMode & 0xF0) | ((driver_led_mode << 2) & 0x0C) );
break;
case LED_TEMP:
u4Addr = TEMP_LED_REGISTER;
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, u4Addr, LED_ADDR_LEN, &u4OldLedMode, LED_DATA_LEN);
u4NewLedMode = ( (u4OldLedMode & 0xCC) | ((driver_led_mode << 4) & 0x30) );
break;
default:
rv = ONLP_STATUS_E_PARAM;
AIM_LOG_ERROR("Invalid LED ID!!\n");
}
if(rv == ONLP_STATUS_OK)
{
rv = ifnOS_LINUX_BmcI2CSet(I2C_BUS, CPLD_ADDR, u4Addr, LED_ADDR_LEN, u4NewLedMode, LED_DATA_LEN);
}
return rv;
}

View File

@@ -0,0 +1,11 @@
###############################################################################
#
#
#
###############################################################################
LIBRARY := x86_64_delta_wb2448
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
#$(LIBRARY)_LAST := 1
include $(BUILDER)/lib.mk

View File

@@ -0,0 +1,311 @@
/************************************************************
* <bsn.cl fy=2017 v=onl>
*
* Copyright 2017 Delta Networks, Inc.
*
* 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>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <AIM/aim.h>
#include <onlp/onlp.h>
#include "platform_lib.h"
/****************************************************************************
* FUNCTION : ifnOS_LINUX_BmcI2CGet
* DESCRIPTION : To read data through BMC I2C
* INPUT : u1Bus
* u1Dev
* u4Addr
* u1AddrLen
* u1DataLen
* OUTPUT : pu4RetData
* RETURN : ONLP_STATUS_OK
****************************************************************************/
INT4 ifnOS_LINUX_BmcI2CGet(UINT1 u1Bus, UINT1 u1Dev, UINT4 u4Addr, UINT1 u1AddrLen, UINT4 *pu4RetData, UINT1 u1DataLen)
{
INT4 i = 0;
INT4 i4Cnt = 1;
INT4 i4Ret = ONLP_STATUS_OK;
UINT4 u4Data = 0;
FILE *pFd = NULL;
UINT1 au1Temp[2] = {0};
INT1 ai1Cmd [OS_MAX_MSG_SIZE] = {0};
INT1 ai1Data[OS_MAX_MSG_SIZE] = {0};
sprintf(ai1Cmd, "ipmitool raw 0x38 0x2 %d %d %d %d", u1Bus, u1Dev, u4Addr, u1DataLen);
pFd = popen(ai1Cmd, "r");
if(pFd != NULL)
{
if (fgets(ai1Data, OS_MAX_MSG_SIZE, pFd) != NULL)
{
while (i < u1DataLen)
{
au1Temp[0] = ai1Data[i4Cnt++];
au1Temp[1] = ai1Data[i4Cnt++];
i4Cnt++;
u4Data <<= (i*8);
u4Data += (UINT1)MMI_XTOI(au1Temp);
i++;
}
*pu4RetData = u4Data;
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Command \"%s\": Get Data Failed (ret: %d)", ai1Cmd, i4Ret);
}
pclose(pFd);
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Execute command \"%s\" failed (ret: %d)", ai1Cmd, i4Ret);
}
return i4Ret;
}
/****************************************************************************
* FUNCTION : ifnOS_LINUX_BmcI2CSet
* DESCRIPTION : To write data through BMC I2C
* INPUT : u1Bus
* u1Dev
* u4Addr
* u1AddrLen
* u4Data
* u1DataLen
* OUTPUT : N/A
* RETURN : ONLP_STATUS_OK
****************************************************************************/
INT4 ifnOS_LINUX_BmcI2CSet(UINT1 u1Bus, UINT1 u1Dev, UINT4 u4Addr, UINT1 u1AddrLen, UINT4 u4Data, UINT1 u1DataLen)
{
INT4 i4Ret = ONLP_STATUS_OK;
FILE *pFd = NULL;
INT1 ai1Cmd[OS_MAX_MSG_SIZE] = {0};
switch (u1DataLen)
{
case 1:
sprintf(ai1Cmd, "ipmitool raw 0x38 0x3 %d %d %d %d", u1Bus, u1Dev, u4Addr, u4Data);
break;
case 2:
sprintf(ai1Cmd, "ipmitool raw 0x38 0x4 %d %d %d %d %d", u1Bus, u1Dev, u4Addr, ((u4Data&0xFF00)>>8), (u4Data&0xFF));
break;
case 4:
sprintf(ai1Cmd, "ipmitool raw 0x38 0x5 %d %d %d %d %d %d %d", u1Bus, u1Dev, u4Addr, ((u4Data&0xFF000000)>>24), ((u4Data&0xFF0000)>>16), ((u4Data&0xFF00)>>8), (u4Data&0xFF));
break;
default:
AIM_LOG_ERROR("ERR: Unsupported data length: %d", u1DataLen);
}
pFd = popen(ai1Cmd, "r");
if (pFd != NULL)
{
pclose(pFd);
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Execute command \"%s\" failed (ret: %d)", ai1Cmd, i4Ret);
}
return i4Ret;
}
/****************************************************************************
* FUNCTION : ifnOS_LINUX_BmcI2CProbe
* DESCRIPTION : To probe device through BMC I2C
* INPUT : u1Bus
* u1Dev
* OUTPUT :
* RETURN : ONLP_STATUS_OK
****************************************************************************/
INT4 ifnOS_LINUX_BmcI2CProbe(UINT1 u1Bus, UINT1 u1Dev)
{
INT4 i4Ret = ONLP_STATUS_OK;
INT4 i4Cnt = 1;
UINT4 u4Data = 0;
UINT1 au1Temp[2] = {0};
INT1 ai1Cmd [OS_MAX_MSG_SIZE] = {0};
INT1 ai1Data[OS_MAX_MSG_SIZE] = {0};
FILE *pFd = NULL;
sprintf(ai1Cmd, "ipmitool raw 0x38 0x1 %d %d", u1Bus, u1Dev);
pFd = popen(ai1Cmd, "r");
if(pFd != NULL)
{
if (fgets(ai1Data, OS_MAX_MSG_SIZE, pFd) != NULL)
{
au1Temp[0] = ai1Data[i4Cnt++];
au1Temp[1] = ai1Data[i4Cnt++];
u4Data += (UINT1)MMI_XTOI(au1Temp);
if (u4Data != 0x00)
AIM_LOG_ERROR("Probe failed (ret: %d)", i4Ret);
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Command \"%s\": Get Data Failed (ret: %d)", ai1Cmd, i4Ret);
}
pclose(pFd);
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Execute command \"%s\" failed (ret: %d)", ai1Cmd, i4Ret);
}
return i4Ret;
}
/****************************************************************************
* FUNCTION : ifnBmcFanSpeedGet
* DESCRIPTION : To Get Fan Speed from Ipmitool
* INPUT : pi1FanName
* pu4RetData
* OUTPUT :
* RETURN : ONLP_STATUS_OK
****************************************************************************/
INT4 ifnBmcFanSpeedGet(INT1 *pi1FanName, UINT4 *pu4RetData)
{
INT4 i4Ret = ONLP_STATUS_OK;
UINT4 u4Data = 0;
INT1 ai1Cmd [OS_MAX_MSG_SIZE] = {0};
INT1 au1Data[OS_MAX_MSG_SIZE] = {0};
INT1 *pui1Temp = NULL;
FILE *pFd = NULL;
sprintf(ai1Cmd, "ipmitool sdr | grep %s", pi1FanName);
pFd = popen(ai1Cmd, "r");
if(pFd != NULL)
{
if (fgets(au1Data, OS_MAX_MSG_SIZE, pFd) != NULL)
{
pui1Temp = strchr(au1Data, '|');
do
{
u4Data += strtol(pui1Temp, &pui1Temp, 10);
}while (*pui1Temp++);
*pu4RetData = u4Data;
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Command \"%s\": Get Data Failed (ret: %d)", ai1Cmd, i4Ret);
}
pclose(pFd);
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Execute command \"%s\" failed (ret: %d)", ai1Cmd, i4Ret);
}
return i4Ret;
}
/****************************************************************************
* FUNCTION : ifnBmcFanSpeedSet
* DESCRIPTION : To Set Fan Speed from Ipmitool
* INPUT : u4FanNumber
* u4Percentage
* OUTPUT :
* RETURN : ONLP_STATUS_OK
****************************************************************************/
INT4 ifnBmcFanSpeedSet(UINT4 u4FanNumber, UINT4 u4Percentage)
{
INT1 ai1Cmd[OS_MAX_MSG_SIZE] = {0};
INT4 i4Ret = ONLP_STATUS_OK;
FILE *pFd = NULL;
sprintf(ai1Cmd, "ipmitool raw 0x38 0xB %d %d", u4FanNumber, u4Percentage);
pFd = popen(ai1Cmd, "r");
if (pFd != NULL)
{
pclose(pFd);
}
else
{
i4Ret = ONLP_STATUS_E_INTERNAL;
AIM_LOG_ERROR("Execute command \"%s\" failed (ret: %d)", ai1Cmd, i4Ret);
}
return i4Ret;
}
UINT4 MMI_XTOI (const UINT1* str)
{
INT4 digit = 0;
UINT4 x = 0;
if ((*str == '0') && (*(str+1) == 'x')) str += 2;
while (*str)
{
if ((*str >= '0') && (*str <= '9'))
{
digit = *str - '0';
}
else if ((*str >= 'A') && (*str <= 'F'))
{
digit = 10 + *str - 'A';
}
else if ((*str >= 'a') && (*str <= 'f'))
{
digit = 10 + *str - 'a';
}
else
{
break;
}
x *= 16;
x += digit;
str++;
}
return x;
}

View File

@@ -0,0 +1,47 @@
/************************************************************
* <bsn.cl fy=2017 v=onl>
*
* Copyright 2017 Delta Networks, Inc.
*
* 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_delta_wb2448_log.h"
typedef unsigned int UINT4;
typedef unsigned short UINT2;
typedef unsigned char UINT1;
typedef int INT4;
typedef short INT2;
typedef char INT1;
#define OS_MAX_MSG_SIZE 100
INT4 ifnOS_LINUX_BmcI2CGet(UINT1 u1Bus, UINT1 u1Dev, UINT4 u4Addr, UINT1 u1AddrLen, UINT4 *pu4RetData, UINT1 u1DataLen);
INT4 ifnOS_LINUX_BmcI2CSet(UINT1 u1Bus, UINT1 u1Dev, UINT4 u4Addr, UINT1 u1AddrLen, UINT4 u4Data, UINT1 u1DataLen);
INT4 ifnOS_LINUX_BmcI2CProbe(UINT1 u1Bus, UINT1 u1Dev);
INT4 ifnBmcFanSpeedGet(INT1 *pi1FanName, UINT4 *pu4RetData);
INT4 ifnBmcFanSpeedSet(UINT4 u4FanNumber, UINT4 u4Percentage);
UINT4 MMI_XTOI (const UINT1* str);
#endif /* __PLATFORM_LIB_H__ */

View File

@@ -0,0 +1,123 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014, 2015 Big Switch Networks, Inc.
* Copyright 2017 Delta Networks, Inc.
*
* 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 "x86_64_delta_wb2448_int.h"
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <onlplib/mmap.h>
#include "platform_lib.h"
#define VALIDATE(_id) \
do \
{ \
if(!ONLP_OID_IS_PSU(_id)) \
{ \
return ONLP_STATUS_E_INVALID; \
} \
} while(0)
#define I2C_BUS 0x04
#define CPLD_ADDR 0x28
#define PSU_PRESENT_REGISTER 0x04
#define PSU_STATUS_REGISTER 0x05
#define PSU_ADDR_LEN 1
#define PSU_DATA_LEN 1
#define PSU_STATUS_ALL_GOOD 0xbf
#define PSU_STATUS_PRESENT 0x30
#define PSU_ID 1
/*
* Get all information about the given PSU oid.
*/
static onlp_psu_info_t pinfo[] =
{
{ }, /* Not used */
{
{ ONLP_PSU_ID_CREATE(PSU_ID), "PSU", 0 },
}
};
int
onlp_psui_init(void)
{
return ONLP_STATUS_OK;
}
int
onlp_psui_info_get(onlp_oid_t id, onlp_psu_info_t* info)
{
INT4 rv = ONLP_STATUS_OK;
UINT4 u4PSUStatus = 0;
VALIDATE(id);
*info = pinfo[ONLP_OID_ID_GET(id)];
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, PSU_PRESENT_REGISTER, PSU_ADDR_LEN, &u4PSUStatus, PSU_DATA_LEN);
if(rv == ONLP_STATUS_OK)
{
if (u4PSUStatus != PSU_STATUS_PRESENT)
{
info->status &= ~ONLP_PSU_STATUS_PRESENT;
return ONLP_STATUS_OK;
}
}
else
{
AIM_LOG_ERROR("Unable to read PSU present status: %d\r\n", rv);
}
info->status |= ONLP_PSU_STATUS_PRESENT;
u4PSUStatus = 0;
rv = ifnOS_LINUX_BmcI2CGet(I2C_BUS, CPLD_ADDR, PSU_STATUS_REGISTER, PSU_ADDR_LEN, &u4PSUStatus, PSU_DATA_LEN);
if(rv == ONLP_STATUS_OK)
{
if (u4PSUStatus != PSU_STATUS_ALL_GOOD)
{
info->status |= ONLP_PSU_STATUS_FAILED;
}
}
else
{
AIM_LOG_ERROR("Unable to read PSU failed/good status: %d\r\n", rv);
}
return rv;
}
int
onlp_psui_ioctl(onlp_oid_t pid, va_list vargs)
{
return ONLP_STATUS_E_UNSUPPORTED;
}

Some files were not shown because too many files have changed in this diff Show More