From 9cba1bf39c02f7545faa88b366433c51c47c1e65 Mon Sep 17 00:00:00 2001 From: Fuzail Khan Date: Mon, 23 Jan 2023 02:38:09 -0800 Subject: [PATCH 1/4] Adding support for FPGAPCIe in PDDF --- platform/pddf/i2c/modules/fpgapci/Makefile | 4 + .../pddf/i2c/modules/fpgapci/algos/Makefile | 4 + .../algos/pddf_xilinx_device_7021_algo.c | 412 ++++++++++++++++++ .../pddf/i2c/modules/fpgapci/driver/Makefile | 4 + .../fpgapci/driver/pddf_fpgapci_driver.c | 347 +++++++++++++++ .../i2c/modules/fpgapci/pddf_fpgapci_module.c | 142 ++++++ .../i2c/modules/include/pddf_fpgapci_defs.h | 49 +++ .../pddf/i2c/modules/include/pddf_i2c_algo.h | 36 ++ 8 files changed, 998 insertions(+) create mode 100644 platform/pddf/i2c/modules/fpgapci/Makefile create mode 100644 platform/pddf/i2c/modules/fpgapci/algos/Makefile create mode 100644 platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c create mode 100644 platform/pddf/i2c/modules/fpgapci/driver/Makefile create mode 100644 platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c create mode 100644 platform/pddf/i2c/modules/fpgapci/pddf_fpgapci_module.c create mode 100644 platform/pddf/i2c/modules/include/pddf_fpgapci_defs.h create mode 100644 platform/pddf/i2c/modules/include/pddf_i2c_algo.h diff --git a/platform/pddf/i2c/modules/fpgapci/Makefile b/platform/pddf/i2c/modules/fpgapci/Makefile new file mode 100644 index 000000000000..12b9830cef77 --- /dev/null +++ b/platform/pddf/i2c/modules/fpgapci/Makefile @@ -0,0 +1,4 @@ +obj-m := driver/ algos/ +obj-m += pddf_fpgapci_module.o + +ccflags-y:= -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fpgapci/algos/Makefile b/platform/pddf/i2c/modules/fpgapci/algos/Makefile new file mode 100644 index 000000000000..91d6954711fb --- /dev/null +++ b/platform/pddf/i2c/modules/fpgapci/algos/Makefile @@ -0,0 +1,4 @@ +# Sample driver for Xilinx 7021 FPGA device +obj-m += pddf_xilinx_device_7021_algo.o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c b/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c new file mode 100644 index 000000000000..4970b06c251e --- /dev/null +++ b/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c @@ -0,0 +1,412 @@ +/* +* +* Licensed under the GNU General Public License Version 2 +* +* 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. +* +*/ + +/* +* pddf_xilinx_device_7021_algo.c +* Description: +* A sample i2c driver algorithms for Xilinx Corporation Device 7021 FPGA adapters +* +*********************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include "pddf_i2c_algo.h" + +#define DEBUG 0 + +enum { + STATE_DONE = 0, + STATE_INIT, + STATE_ADDR, + STATE_ADDR10, + STATE_START, + STATE_WRITE, + STATE_READ, + STATE_STOP, + STATE_ERROR, +}; + +/* registers */ +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 + +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 + +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 + +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 + +struct fpgalogic_i2c { + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; +}; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +extern void __iomem * fpga_ctl_addr; +extern int (*ptr_fpgapci_read)(uint32_t); +extern int (*ptr_fpgapci_write)(uint32_t, uint32_t); +extern int (*pddf_i2c_pci_add_numbered_bus)(struct i2c_adapter *, int); + +void i2c_get_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_lock(&i2c->lock); +} + +/** + * i2c_release_mutex - release mutex + */ +void i2c_release_mutex(struct fpgalogic_i2c *i2c) +{ + mutex_unlock(&i2c->lock); +} + +static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); +} + +static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) +{ + return ioread8(i2c->base + (reg << i2c->reg_shift)); +} + +static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) +{ + i2c->reg_set(i2c, reg, value); + udelay(100); +} + +static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) +{ + udelay(100); + return i2c->reg_get(i2c, reg); +} + + +/* + * i2c_get_mutex must be called prior to calling this function. + */ +static int fpgai2c_poll(struct fpgalogic_i2c *i2c) +{ + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } + + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + + return 0; + } + + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + + i2c->state = STATE_START; + return 0; + } + + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } + + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } + + return 0; +} + +static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct fpgalogic_i2c *i2c = i2c_get_adapdata(adap); + int ret; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + i2c->msg = msgs; + i2c->pos = 0; + i2c->nmsgs = num; + i2c->state = STATE_INIT; + + /* Handle the transfer */ + while (time_before(jiffies, timeout)) { + i2c_get_mutex(i2c); + ret = fpgai2c_poll(i2c); + i2c_release_mutex(i2c); + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) + return (i2c->state == STATE_DONE) ? num : ret; + + if (ret == 0) + timeout = jiffies + HZ; + + usleep_range(5, 15); + } + printk("[%s] ERROR STATE_ERROR\n", __FUNCTION__); + + i2c->state = STATE_ERROR; + + return -ETIMEDOUT; + +} + +static u32 fpgai2c_func(struct i2c_adapter *adap) +{ +/* a typical full-I2C adapter would use the following */ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm fpgai2c_algorithm= { + .master_xfer = fpgai2c_xfer, /*write I2C messages */ + .functionality = fpgai2c_func, /* what the adapter supports */ +}; + +static int fpgai2c_init(struct fpgalogic_i2c *i2c) +{ + int prescale; + int diff; + u8 ctrl; + + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); + + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); + + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + printk("[%s] ERROR Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + __FUNCTION__, i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } + + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + return 0; +} + +static int adap_data_init(struct i2c_adapter *adap, int i2c_ch_index) +{ + struct fpgapci_devdata *pci_privdata = 0; + pci_privdata = (struct fpgapci_devdata*) dev_get_drvdata(adap->dev.parent); + + if (pci_privdata == 0) { + printk("[%s]: ERROR pci_privdata is 0\n", __FUNCTION__); + return -1; + } +#if DEBUG + pddf_dbg(FPGA, KERN_INFO "[%s] index: [%d] fpga_data__base_addr:0x%0x8lx" + " fpgapci_bar_len:0x%08lx fpga_i2c_ch_base_addr:0x%08lx ch_size=0x%x supported_i2c_ch=%d", + __FUNCTION__, i2c_ch_index, pci_privdata->fpga_data_base_addr, + pci_privdata->bar_length, pci_privdata->fpga_i2c_ch_base_addr, + pci_privdata->fpga_i2c_ch_size, pci_privdata->max_fpga_i2c_ch); +#endif + if (i2c_ch_index >= pci_privdata->max_fpga_i2c_ch || pci_privdata->max_fpga_i2c_ch > I2C_PCI_MAX_BUS) { + printk("[%s]: ERROR i2c_ch_index=%d max_ch_index=%d out of range: %d\n", + __FUNCTION__, i2c_ch_index, pci_privdata->max_fpga_i2c_ch, I2C_PCI_MAX_BUS); + return -1; + } + + memset (&fpgalogic_i2c[i2c_ch_index], 0, sizeof(fpgalogic_i2c[0])); + /* Initialize driver's itnernal data structures */ + fpgalogic_i2c[i2c_ch_index].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i2c_ch_index].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i2c_ch_index].timeout = 500;//1000;//1ms + fpgalogic_i2c[i2c_ch_index].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i2c_ch_index].bus_clock_khz = 100; + fpgalogic_i2c[i2c_ch_index].base = pci_privdata->fpga_i2c_ch_base_addr + + i2c_ch_index* pci_privdata->fpga_i2c_ch_size; + mutex_init(&fpgalogic_i2c[i2c_ch_index].lock); + fpgai2c_init(&fpgalogic_i2c[i2c_ch_index]); + + + adap->algo_data = &fpgalogic_i2c[i2c_ch_index]; + i2c_set_adapdata(adap, &fpgalogic_i2c[i2c_ch_index]); + return 0; +} + +static int pddf_i2c_pci_add_numbered_bus_default (struct i2c_adapter *adap, int i2c_ch_index) +{ + int ret = 0; + + adap_data_init(adap, i2c_ch_index); + adap->algo = &fpgai2c_algorithm; + + ret = i2c_add_numbered_adapter(adap); + return ret; +} + +/* + * FPGAPCI APIs + */ +int board_i2c_fpgapci_read(uint32_t offset) +{ + int data; + data=ioread32(fpga_ctl_addr+offset); + return data; +} + + +int board_i2c_fpgapci_write(uint32_t offset, uint32_t value) +{ + iowrite32(value, fpga_ctl_addr+offset); + return (0); +} + + +static int __init pddf_xilinx_device_7021_algo_init(void) +{ + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + pddf_i2c_pci_add_numbered_bus = pddf_i2c_pci_add_numbered_bus_default; + ptr_fpgapci_read = board_i2c_fpgapci_read; + ptr_fpgapci_write = board_i2c_fpgapci_write; + return 0; +} + +static void __exit pddf_xilinx_device_7021_algo_exit(void) +{ + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + + pddf_i2c_pci_add_numbered_bus = NULL; + ptr_fpgapci_read = NULL; + ptr_fpgapci_write = NULL; + return; +} + + +module_init (pddf_xilinx_device_7021_algo_init); +module_exit (pddf_xilinx_device_7021_algo_exit); +MODULE_DESCRIPTION("Xilinx Corporation Device 7021 FPGAPCIe I2C-Bus algorithm"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/fpgapci/driver/Makefile b/platform/pddf/i2c/modules/fpgapci/driver/Makefile new file mode 100644 index 000000000000..1ea8b612734f --- /dev/null +++ b/platform/pddf/i2c/modules/fpgapci/driver/Makefile @@ -0,0 +1,4 @@ +TARGET = pddf_fpgapci_driver +obj-m := $(TARGET).o + +ccflags-y := -I$(M)/modules/include diff --git a/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c b/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c new file mode 100644 index 000000000000..5cf8130001a6 --- /dev/null +++ b/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c @@ -0,0 +1,347 @@ +/* +* +* Licensed under the GNU General Public License Version 2 +* +* 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. +* +*/ + +/* +* pddf_fpgapci_driver.c +* Description: +* This is a PDDF FPGAPCIe driver whic creates the PCIE device and add +* the i2c adapters to it. It uses the adapter creation and fpgapcie +* read/write functions defined separately in another kernel module. +* +************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //siginfo +#include //rcu_read_lock +#include //kernel_version +#include +#include +#include +#include +#include +#include "pddf_fpgapci_defs.h" +#include "pddf_client_defs.h" +#include "pddf_i2c_algo.h" + + + +#define DEBUG 0 +int (*pddf_i2c_pci_add_numbered_bus)(struct i2c_adapter *, int) = NULL; +int (*ptr_fpgapci_read)(uint32_t) = NULL; +int (*ptr_fpgapci_write)(uint32_t, uint32_t) = NULL; +EXPORT_SYMBOL(pddf_i2c_pci_add_numbered_bus); +EXPORT_SYMBOL(ptr_fpgapci_read); +EXPORT_SYMBOL(ptr_fpgapci_write); + +FPGA_OPS_DATA pddf_fpga_ops_data={0}; + +#define DRIVER_NAME "pddf_fpgapci" +#define MAX_PCI_NUM_BARS 6 + +struct pci_driver pddf_fpgapci_driver; +struct pci_device_id *pddf_fpgapci_ids=NULL; +int total_i2c_pci_bus=0; +int FPGAPCI_BAR_INDEX = -1; + +void __iomem * fpga_ctl_addr = NULL; +EXPORT_SYMBOL(fpga_ctl_addr); + +static int pddf_fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void pddf_fpgapci_remove(struct pci_dev *dev); +static int map_bars(struct fpgapci_devdata *pci_privdata, struct pci_dev *dev); +static void free_bars(struct fpgapci_devdata *pci_privdata, struct pci_dev *dev); +static int pddf_pci_add_adapter(struct pci_dev *dev); + +/* each i2c bus is represented in linux using struct i2c_adapter */ +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; + +static int pddf_pci_add_adapter(struct pci_dev *dev) +{ + int i; + + total_i2c_pci_bus = pddf_fpga_ops_data.virt_i2c_ch; + pddf_dbg(FPGA, KERN_INFO "[%s] total_i2c_pci_bus=%d\n", __FUNCTION__, total_i2c_pci_bus); + + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + + for (i = 0 ; i < total_i2c_pci_bus; i ++) { + + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + + /* /dev/i2c-xxx for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i + pddf_fpga_ops_data.virt_bus ; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + + /* set up the sysfs linkage to our parent device */ + i2c_pci_adap[i].dev.parent = &dev->dev; + + /* Add the bus via the algorithm code */ + + if( (pddf_i2c_pci_add_numbered_bus!=NULL) && (pddf_i2c_pci_add_numbered_bus( &i2c_pci_adap[ i ], i ) != 0 )) + { + pddf_dbg(FPGA, KERN_ERR "Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + pddf_dbg(FPGA, KERN_INFO "[%s] Registered bus id: %s\n", __FUNCTION__, kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } + + return 0; +} + +static void pddf_pci_del_adapter(void) +{ + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } +} + +static int map_bars(struct fpgapci_devdata *pci_privdata, struct pci_dev *dev) +{ + unsigned long barFlags, barStart, barEnd, barLen; + int i; + + for (i=0; i < MAX_PCI_NUM_BARS; i++) { + if((barLen=pci_resource_len(dev, i)) !=0 && (barStart=pci_resource_start(dev, i)) !=0 ) { + barFlags = pci_resource_flags(dev, i); + barEnd = pci_resource_end(dev, i); + pddf_dbg(FPGA, KERN_INFO "[%s] PCI_BASE_ADDRESS_%d 0x%08lx-0x%08lx bar_len=0x%lx" + " flags 0x%08lx IO_mapped=%s Mem_mapped=%s\n", __FUNCTION__, + i, barStart, barEnd, barLen, barFlags, (barFlags & IORESOURCE_IO)? "Yes": "No", + (barFlags & IORESOURCE_MEM)? "Yes" : "No"); + FPGAPCI_BAR_INDEX=i; + break; + } + } + + if (FPGAPCI_BAR_INDEX != -1) { + pci_privdata->bar_length = barLen; + pci_privdata->fpga_data_base_addr = ioremap_cache (barStart + pddf_fpga_ops_data.data_base_offset, + pddf_fpga_ops_data.data_size); + fpga_ctl_addr = pci_privdata->fpga_data_base_addr; + + pci_privdata->fpga_i2c_ch_base_addr = ioremap_cache (barStart + pddf_fpga_ops_data.i2c_ch_base_offset, + I2C_PCI_MAX_BUS * pddf_fpga_ops_data.i2c_ch_size); + pci_privdata->max_fpga_i2c_ch = pddf_fpga_ops_data.virt_i2c_ch; + pci_privdata->fpga_i2c_ch_size = pddf_fpga_ops_data.i2c_ch_size; + } else { + pddf_dbg(FPGA, KERN_INFO "[%s] Failed to find BAR\n", __FUNCTION__); + return (-1); + } + pddf_dbg(FPGA, KERN_INFO "[%s] fpga_ctl_addr:0x%p fpga_data__base_addr:0x%p" + " bar_index[%d] fpgapci_bar_len:0x%08lx fpga_i2c_ch_base_addr:0x%p supported_i2c_ch=%d", + __FUNCTION__, fpga_ctl_addr, pci_privdata->fpga_data_base_addr, FPGAPCI_BAR_INDEX, + pci_privdata->bar_length, pci_privdata->fpga_i2c_ch_base_addr, pci_privdata->max_fpga_i2c_ch); + + return 0; +} + +static void free_bars(struct fpgapci_devdata *pci_privdata, struct pci_dev *dev) +{ + pci_iounmap(dev, pci_privdata->fpga_data_base_addr); + pci_privdata->fpga_i2c_ch_base_addr = NULL; +} + +static int pddf_pci_config_data(struct pci_dev *dev) +{ + unsigned short vendorId=0xFFFF, deviceId=0xFFFF; + char revisionId=0xFF, classDev=0xFF, classProg=0xFF; + char irqLine=0xFF, irqPin=0xFF; + + pddf_dbg(FPGA, KERN_INFO "[%s] PCI Config Data\n", __FUNCTION__); + + /* accessing the configuration region of the PCI device */ + pci_read_config_word(dev, PCI_VENDOR_ID, &vendorId); + pci_read_config_word(dev, PCI_DEVICE_ID, &deviceId); + pci_read_config_byte(dev, PCI_REVISION_ID, &revisionId); + pci_read_config_byte(dev, PCI_CLASS_PROG, &classProg); + pci_read_config_byte(dev, PCI_CLASS_DEVICE, &classDev); + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irqPin); + if(pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irqLine)) { + pddf_dbg(FPGA, KERN_ERR "\tPCI_INTERRUPT_LINE Error\n"); + } + + pddf_dbg(FPGA, KERN_INFO "\t[venId, devId]=[0x%x;0x%x] [group, class]=[%x;%x]\n", + vendorId, deviceId, classProg, classDev); + pddf_dbg(FPGA, KERN_INFO "\trevsionId=0x%x, irq_line=0x%x, irq_support=%s\n", + revisionId, irqLine, (irqPin == 0)? "No":"Yes"); + + return (0); +} + + +static int pddf_fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + struct fpgapci_devdata *pci_privdata = 0; + int err = 0; + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + + if ((err = pci_enable_device(dev))) { + pddf_dbg(FPGA, KERN_ERR "[%s] pci_enable_device failed. dev:%s err:%#x\n", + __FUNCTION__, pci_name(dev), err); + return (err); + } + + /* Enable DMA */ + pci_set_master(dev); + + /* Request MMIO/IOP resources - reserve PCI I/O and memory resources + DRIVE_NAME shows up in /proc/iomem + */ + if ((err = pci_request_regions(dev, DRIVER_NAME)) < 0) { + pddf_dbg(FPGA, KERN_ERR "[%s] pci_request_regions failed. dev:%s err:%#x\n", + __FUNCTION__, pci_name(dev), err); + goto error_pci_req; + } + + pci_privdata = kzalloc(sizeof(struct fpgapci_devdata), GFP_KERNEL); + + if (!pci_privdata) { + pddf_dbg(FPGA, KERN_ERR "[%s] couldn't allocate pci_privdata memory", __FUNCTION__); + goto error_pci_req; + } + + pci_privdata->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)pci_privdata); + pddf_pci_config_data(dev); + + if (map_bars(pci_privdata, dev)) { + pddf_dbg(FPGA, KERN_ERR "error_map_bars\n"); + goto error_map_bars; + } + pddf_pci_add_adapter(dev); + return (0); + +/* ERROR HANDLING */ +error_map_bars: + pci_release_regions(dev); +error_pci_req: + pci_disable_device(dev); + return -ENODEV; + +} + +static void pddf_fpgapci_remove(struct pci_dev *dev) +{ + struct fpgapci_devdata *pci_privdata = 0; + + if (dev == 0) { + pddf_dbg(FPGA, KERN_ERR "[%s]: dev is 0\n", __FUNCTION__); + return; + } + + pci_privdata = (struct fpgapci_devdata*) dev_get_drvdata(&dev->dev); + + if (pci_privdata == 0) { + pddf_dbg(FPGA, KERN_ERR "[%s]: pci_privdata is 0\n", __FUNCTION__); + return; + } + + pddf_pci_del_adapter(); + free_bars (pci_privdata, dev); + pci_disable_device(dev); + pci_release_regions(dev); + kfree (pci_privdata); +} + + +/* Initialize the driver module (but not any device) and register + * the module with the kernel PCI subsystem. */ +int pddf_fpgapci_register(FPGA_OPS_DATA* ptr_ops_data) +{ + + memcpy(&pddf_fpga_ops_data, ptr_ops_data, sizeof(FPGA_OPS_DATA)); +#if DEBUG + pddf_dbg(FPGA, KERN_INFO "[%s]: pddf_fpga_ops_data vendor_id=0x%x device_id=0x%x virt_bus=0x%x " + " data_base_offset=0x%x data_size=0x%x i2c_ch_base_offset=0x%x i2c_ch_size=0x%x virt_i2c_ch=%d", + __FUNCTION__, pddf_fpga_ops_data.vendor_id, pddf_fpga_ops_data.device_id, + pddf_fpga_ops_data.virt_bus, pddf_fpga_ops_data.data_base_offset, pddf_fpga_ops_data.data_size, + pddf_fpga_ops_data.i2c_ch_base_offset, pddf_fpga_ops_data.i2c_ch_size, + pddf_fpga_ops_data.virt_i2c_ch); +#endif + struct pci_device_id fpgapci_ids[2] = { + {PCI_DEVICE(pddf_fpga_ops_data.vendor_id, pddf_fpga_ops_data.device_id)}, + {0, }, + }; + + int size = sizeof(struct pci_device_id) * 2; + + if ((pddf_fpgapci_ids=kmalloc(size, GFP_KERNEL)) == NULL) { + pddf_dbg(FPGA, KERN_INFO "%s kmalloc failed\n", __FUNCTION__); + return 0; + } + + memcpy(pddf_fpgapci_ids, fpgapci_ids, size); + + pddf_fpgapci_driver.name=DRIVER_NAME; + pddf_fpgapci_driver.id_table=pddf_fpgapci_ids; + pddf_fpgapci_driver.probe=pddf_fpgapci_probe; + pddf_fpgapci_driver.remove=pddf_fpgapci_remove; + + if (pci_register_driver(&pddf_fpgapci_driver)) { + pddf_dbg(FPGA, KERN_INFO "%s: pci_unregister_driver\n", __FUNCTION__); + pci_unregister_driver(&pddf_fpgapci_driver); + return -ENODEV; + } + return 0; +} + +EXPORT_SYMBOL(pddf_fpgapci_register); + +static int __init pddf_fpgapci_driver_init(void) +{ + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + + return 0; +} + +static void __exit pddf_fpgapci_driver_exit(void) +{ + pddf_dbg(FPGA, KERN_INFO "[%s]\n", __FUNCTION__); + + if (pddf_fpgapci_ids) { + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&pddf_fpgapci_driver); + kfree(pddf_fpgapci_ids); + } + +} + + +module_init (pddf_fpgapci_driver_init); +module_exit (pddf_fpgapci_driver_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION ("PDDF Driver for FPGAPCI Logic I2C bus"); +MODULE_SUPPORTED_DEVICE ("PDDF FPGAPCI Logic I2C bus"); diff --git a/platform/pddf/i2c/modules/fpgapci/pddf_fpgapci_module.c b/platform/pddf/i2c/modules/fpgapci/pddf_fpgapci_module.c new file mode 100644 index 000000000000..72ec97c1e2f3 --- /dev/null +++ b/platform/pddf/i2c/modules/fpgapci/pddf_fpgapci_module.c @@ -0,0 +1,142 @@ +/* + * + * 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. + * + * A pddf kernel module to create sysfs for fpga + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pddf_client_defs.h" +#include "pddf_fpgapci_defs.h" + +FPGA_OPS_DATA tmp_pddf_fpga_ops_data={0}; +extern int pddf_fpgapci_register(FPGA_OPS_DATA *ptr); + +/************************************************************************** + * FPGA SYSFS Attributes + **************************************************************************/ +static ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +PDDF_DATA_ATTR(vendor_id, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.vendor_id, NULL); +PDDF_DATA_ATTR(device_id, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.device_id, NULL); +PDDF_DATA_ATTR(virt_bus, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.virt_bus, NULL); +PDDF_DATA_ATTR(data_base_offset, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.data_base_offset, NULL); +PDDF_DATA_ATTR(data_size, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.data_size, NULL); +PDDF_DATA_ATTR(i2c_ch_base_offset, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.i2c_ch_base_offset, NULL); +PDDF_DATA_ATTR(i2c_ch_size, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.i2c_ch_size, NULL); +PDDF_DATA_ATTR(virt_i2c_ch, S_IWUSR|S_IRUGO, show_pddf_data, + store_pddf_data, PDDF_UINT32, sizeof(uint32_t), (void*)&tmp_pddf_fpga_ops_data.virt_i2c_ch, NULL); +PDDF_DATA_ATTR(dev_ops , S_IWUSR|S_IRUGO, show_pddf_data, + dev_operation, PDDF_CHAR, NAME_SIZE, (void*)&tmp_pddf_fpga_ops_data, NULL); + +struct attribute* attrs_fpgapci[]={ + &attr_vendor_id.dev_attr.attr, + &attr_device_id.dev_attr.attr, + &attr_virt_bus.dev_attr.attr, + &attr_data_base_offset.dev_attr.attr, + &attr_data_size.dev_attr.attr, + &attr_i2c_ch_base_offset.dev_attr.attr, + &attr_i2c_ch_size.dev_attr.attr, + &attr_virt_i2c_ch.dev_attr.attr, + &attr_dev_ops.dev_attr.attr, + NULL, +}; +struct attribute_group attr_group_fpgapci={ + .attrs = attrs_fpgapci, +}; + +ssize_t dev_operation(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + if(strncmp(buf, "fpgapci_init", strlen("fpgapci_init"))==0 ) { + struct pddf_data_attribute *_ptr = (struct pddf_data_attribute *)da; + FPGA_OPS_DATA* pddf_fpga_ops_data=(FPGA_OPS_DATA*)_ptr->addr; + pddf_dbg(FPGA, KERN_INFO "%s: pddf_fpga_ops_data vendor_id=0x%x device_id=0x%x virt_bus=0x%x:%d " + " data_base_offset=0x%x data_size=0x%x i2c_ch_base_offset=0x%x i2c_ch_size=0x%x virt_i2c_ch=%d", + __FUNCTION__, pddf_fpga_ops_data->vendor_id, pddf_fpga_ops_data->device_id, + pddf_fpga_ops_data->virt_bus, pddf_fpga_ops_data->virt_bus, + pddf_fpga_ops_data->data_base_offset, pddf_fpga_ops_data->data_size, + pddf_fpga_ops_data->i2c_ch_base_offset, pddf_fpga_ops_data->i2c_ch_size, pddf_fpga_ops_data->virt_i2c_ch); + + pddf_fpgapci_register(pddf_fpga_ops_data); + } + else { + pddf_dbg(FPGA, KERN_ERR "PDDF_ERROR %s: Invalid value for dev_ops %s\n", __FUNCTION__, buf); + } + return(count); +} + + +#define KOBJ_FREE(obj) \ + if(obj) kobject_put(obj); \ + + +int __init pddf_fpga_data_init(void) +{ + int ret = 0; + struct kobject *device_kobj; + + pddf_dbg(FPGA, KERN_INFO "%s ..\n", __FUNCTION__); + + device_kobj = get_device_i2c_kobj(); + if(!device_kobj) { + pddf_dbg(FPGA, KERN_ERR "%s get_device_i2c_kobj failed ..\n", __FUNCTION__); + return -ENOMEM; + } + fpgapci_kobj = kobject_create_and_add("fpgapci", device_kobj); + if(!fpgapci_kobj) { + pddf_dbg(FPGA, KERN_ERR "%s create fpgapci kobj failed ..\n", __FUNCTION__); + return -ENOMEM; + } + + ret = sysfs_create_group(fpgapci_kobj, &attr_group_fpgapci); + if (ret) + { + pddf_dbg(FPGA, KERN_ERR "%s create fpga sysfs attributes failed ..\n", __FUNCTION__); + return ret; + } + + + return (0); + +} + +void __exit pddf_fpga_data_exit(void) +{ + pddf_dbg(FPGA, KERN_INFO "%s ..\n", __FUNCTION__); + KOBJ_FREE(fpgapci_kobj) + return; +} + + +module_init(pddf_fpga_data_init); +module_exit(pddf_fpga_data_exit); + +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("fpga platform data"); +MODULE_LICENSE("GPL"); diff --git a/platform/pddf/i2c/modules/include/pddf_fpgapci_defs.h b/platform/pddf/i2c/modules/include/pddf_fpgapci_defs.h new file mode 100644 index 000000000000..c745bbd09f3c --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_fpgapci_defs.h @@ -0,0 +1,49 @@ +/* + * + * 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. + * + * Description: + * Platform FPGAPCI defines/structures header file + */ + +#ifndef __PDDF_FPGAPCI_DEFS_H__ +#define __PDDF_FPGAPCI_DEFS_H__ + + +// FPGA +typedef struct +{ + uint32_t vendor_id; + uint32_t device_id; + uint32_t virt_bus; + uint32_t virt_i2c_ch; + uint32_t data_base_offset; + uint32_t data_size; + uint32_t i2c_ch_base_offset; + uint32_t i2c_ch_size; +} FPGA_OPS_DATA; + +/***************************************** + * kobj list + *****************************************/ + +struct kobject *fpgapci_kobj=NULL; + +/***************************************** + * Static Data provided from user + * space JSON data file + *****************************************/ +#define NAME_SIZE 32 + + + + +#endif diff --git a/platform/pddf/i2c/modules/include/pddf_i2c_algo.h b/platform/pddf/i2c/modules/include/pddf_i2c_algo.h new file mode 100644 index 000000000000..3526b456516a --- /dev/null +++ b/platform/pddf/i2c/modules/include/pddf_i2c_algo.h @@ -0,0 +1,36 @@ +/* + * + * Description: + * This is the required header file for customed i2c algorithms + */ + +#ifndef __PDDF_I2C_ALGO_H__ +#define __PDDF_I2C_ALGO_H__ +#include "pddf_client_defs.h" + +/* max number of adapters */ +#define I2C_PCI_MAX_BUS 16 + +/** + * struct fpgapci_devdata - PCI device data structure + * support one device per PCIe + */ +struct fpgapci_devdata { + struct pci_dev *pci_dev; + + /* kernels virtual addr for fpga_data_base_addr */ + void * __iomem fpga_data_base_addr; + + /* kernels virtual addr. for the i2c_ch_base_addr */ + void * __iomem fpga_i2c_ch_base_addr; + + /* size per i2c_ch */ + int fpga_i2c_ch_size; + + /* number of supported virtual i2c buses */ + int max_fpga_i2c_ch; + + size_t bar_length; +}; + +#endif From 811db74a9bd0449226044ac008161a1744ae29f1 Mon Sep 17 00:00:00 2001 From: Fuzail Khan Date: Sun, 29 Jan 2023 21:26:59 -0800 Subject: [PATCH 2/4] Adding support for FPGAPCIe in PDDF: Fixing semgrep check failure --- .../modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c | 9 +++++++-- .../i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c b/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c index 4970b06c251e..dc2f52bf16c3 100644 --- a/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c +++ b/platform/pddf/i2c/modules/fpgapci/algos/pddf_xilinx_device_7021_algo.c @@ -20,6 +20,8 @@ * A sample i2c driver algorithms for Xilinx Corporation Device 7021 FPGA adapters * *********************************************************************************/ +#define __STDC_WANT_LIB_EXT1__ 1 +#include #include #include #include @@ -338,8 +340,11 @@ static int adap_data_init(struct i2c_adapter *adap, int i2c_ch_index) __FUNCTION__, i2c_ch_index, pci_privdata->max_fpga_i2c_ch, I2C_PCI_MAX_BUS); return -1; } - - memset (&fpgalogic_i2c[i2c_ch_index], 0, sizeof(fpgalogic_i2c[0])); +#ifdef __STDC_LIB_EXT1__ + memset_s(&fpgalogic_i2c[i2c_ch_index], sizeof(fpgalogic_i2c[0]), 0, sizeof(fpgalogic_i2c[0])); +#else + memset(&fpgalogic_i2c[i2c_ch_index], 0, sizeof(fpgalogic_i2c[0])); +#endif /* Initialize driver's itnernal data structures */ fpgalogic_i2c[i2c_ch_index].reg_shift = 0; /* 8 bit registers */ fpgalogic_i2c[i2c_ch_index].reg_io_width = 1; /* 8 bit read/write */ diff --git a/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c b/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c index 5cf8130001a6..630981522b15 100644 --- a/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c +++ b/platform/pddf/i2c/modules/fpgapci/driver/pddf_fpgapci_driver.c @@ -22,6 +22,8 @@ * read/write functions defined separately in another kernel module. * ************************************************************************/ +#define __STDC_WANT_LIB_EXT1__ 1 +#include #include #include #include @@ -90,8 +92,11 @@ static int pddf_pci_add_adapter(struct pci_dev *dev) total_i2c_pci_bus = pddf_fpga_ops_data.virt_i2c_ch; pddf_dbg(FPGA, KERN_INFO "[%s] total_i2c_pci_bus=%d\n", __FUNCTION__, total_i2c_pci_bus); - - memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); +#ifdef __STDC_LIB_EXT1__ + memset_s(&i2c_pci_adap, sizeof(i2c_pci_adap), 0, sizeof(i2c_pci_adap)); +#else + memset(&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); +#endif for (i = 0 ; i < total_i2c_pci_bus; i ++) { From ef8d313aee9941296fc763dc4b630124c803b72a Mon Sep 17 00:00:00 2001 From: Fuzail Khan Date: Mon, 30 Jan 2023 00:46:56 -0800 Subject: [PATCH 3/4] Adding support for FPGAPCIe in PDDF - Including the Makefiles changes in respective PRs --- platform/pddf/i2c/debian/rules | 2 +- platform/pddf/i2c/modules/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/pddf/i2c/debian/rules b/platform/pddf/i2c/debian/rules index 3e0bb7c4ffc9..4ddbbdfd2405 100755 --- a/platform/pddf/i2c/debian/rules +++ b/platform/pddf/i2c/debian/rules @@ -18,7 +18,7 @@ PACKAGE_PRE_NAME := sonic-platform-pddf KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= client cpld cpld/driver cpldmux cpldmux/driver fpgai2c fpgai2c/driver fan fan/driver mux gpio led psu psu/driver sysstatus xcvr xcvr/driver +MODULE_DIRS:= client cpld cpld/driver cpldmux cpldmux/driver fpgai2c fpgai2c/driver fpgapci fpgapci/driver fpgapci/algos fan fan/driver mux gpio led psu psu/driver sysstatus xcvr xcvr/driver MODULE_DIR:= modules UTILS_DIR := utils SERVICE_DIR := service diff --git a/platform/pddf/i2c/modules/Makefile b/platform/pddf/i2c/modules/Makefile index 71c1db661367..a936ff9756c3 100644 --- a/platform/pddf/i2c/modules/Makefile +++ b/platform/pddf/i2c/modules/Makefile @@ -1 +1 @@ -obj-m := client/ cpld/ cpldmux/ fpgai2c/ xcvr/ mux/ gpio/ psu/ fan/ led/ sysstatus/ +obj-m := client/ cpld/ cpldmux/ fpgai2c/ fpgapci/ xcvr/ mux/ gpio/ psu/ fan/ led/ sysstatus/ From 56ba1800426012a20daee5ac83aae1a5cecf28c6 Mon Sep 17 00:00:00 2001 From: Fuzail Khan Date: Mon, 30 Jan 2023 02:17:29 -0800 Subject: [PATCH 4/4] Adding support for FPGAPCIe in PDDF - build failure --- platform/pddf/i2c/modules/include/pddf_client_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/pddf/i2c/modules/include/pddf_client_defs.h b/platform/pddf/i2c/modules/include/pddf_client_defs.h index b9d5090f731f..cb26dd1ab4fa 100644 --- a/platform/pddf/i2c/modules/include/pddf_client_defs.h +++ b/platform/pddf/i2c/modules/include/pddf_client_defs.h @@ -33,6 +33,8 @@ #define GPIO "PDDF_GPIO" #define SYSSTATUS "PDDF_SYSSTATUS" #define XCVR "PDDF_XCVR" +#define FPGA "PDDF_FPGAPCI" + #define PDDF_DEBUG #ifdef PDDF_DEBUG