Skip to content

Commit

Permalink
Enabling FPGA device support in PDDF (sonic-net#13477)
Browse files Browse the repository at this point in the history
Why I did it
To enable FPGA support in PDDF.

How I did it
Added FPGAI2C and FPGAPCI in the build path for the PDDF debian package
Added the support for FPGA access APIs in the drivers of fan, xcvr, led etc.
Added the FPGA device creation support in PDDF utils and parsers

How to verify it
These changes can be verified on some platform using such FPGAs. For testing purpose, we took Dell S5232f platform and brought it up using PDDF. In doing so, FPGA devices are created using PDDF and optics eeproms were accessed using common FPGA drivers. Below are some of the logs.
  • Loading branch information
FuzailBrcm authored and qnos committed Nov 12, 2023
1 parent b23e03a commit 35f40c5
Show file tree
Hide file tree
Showing 11 changed files with 1,133 additions and 536 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/i2c.h>
#include "../../../../../pddf/i2c/modules/include/pddf_led_defs.h"
#include "../../../../../pddf/i2c/modules/include/pddf_client_defs.h"
#include "pddf_led_defs.h"
#include "pddf_client_defs.h"

#define DEBUG 0
LED_OPS_DATA sys_led_ops_data[1]={0};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/hwmon-sysfs.h>
#include "../../../../../pddf/i2c/modules/include/pddf_led_defs.h"
#include "../../../../../pddf/i2c/modules/include/pddf_client_defs.h"
#include "../../../ra-b6510-32c/modules/driver/pddf_led_defs.h"
#include "../../../ra-b6510-32c/modules/driver//pddf_client_defs.h"
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/slab.h>
Expand Down
171 changes: 137 additions & 34 deletions platform/pddf/i2c/modules/fan/driver/pddf_fan_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,106 @@ int fan_cpld_client_read(FAN_DATA_ATTR *udata)
return status;
}

int fan_cpld_client_write(FAN_DATA_ATTR *udata, uint32_t val)
{
int status = 0;

if (udata->len==1)
{
status = board_i2c_cpld_write(udata->devaddr, udata->offset, val);
}
else
{
/* Get the I2C client for the CPLD */
struct i2c_client *client_ptr=NULL;
client_ptr = (struct i2c_client *)get_device_table(udata->devname);
if (client_ptr)
{
if (udata->len==2)
{
uint8_t val_lsb = val & 0xFF;
uint8_t val_hsb = (val >> 8) & 0xFF;
/* TODO: Check this logic for LE and BE */
status = i2c_smbus_write_byte_data(client_ptr, udata->offset, val_lsb);
if (status==0) status = i2c_smbus_write_byte_data(client_ptr, udata->offset+1, val_hsb);
}
else
printk(KERN_ERR "PDDF_FAN: Doesn't support block CPLD write yet");
}
else
printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname);
}

return status;
}

int fan_fpgai2c_client_read(FAN_DATA_ATTR *udata)
{
int status = -1;

if (udata!=NULL)
{
if (udata->len==1)
{
status = board_i2c_fpga_read(udata->devaddr , udata->offset);
/*printk(KERN_ERR "### Reading offset 0x%x from 0x%x device ... val 0x%x\n", udata->offset, udata->devaddr, status);*/
}
else
{
/* Get the I2C client for the FPGAI2C */
struct i2c_client *client_ptr=NULL;
client_ptr = (struct i2c_client *)get_device_table(udata->devname);
if (client_ptr)
{
if (udata->len==2)
{
status = i2c_smbus_read_word_swapped(client_ptr, udata->offset);
}
else
printk(KERN_ERR "PDDF_FAN: Doesn't support block FPGAI2C read yet");
}
else
printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname);
}

}

return status;
}

int fan_fpgai2c_client_write(FAN_DATA_ATTR *udata, uint32_t val)
{
int status = 0;

if (udata->len==1)
{
status = board_i2c_fpga_write(udata->devaddr, udata->offset, val);
}
else
{
/* Get the I2C client for the FPGAI2C */
struct i2c_client *client_ptr=NULL;
client_ptr = (struct i2c_client *)get_device_table(udata->devname);
if (client_ptr)
{
if (udata->len==2)
{
uint8_t val_lsb = val & 0xFF;
uint8_t val_hsb = (val >> 8) & 0xFF;
/* TODO: Check this logic for LE and BE */
status = i2c_smbus_write_byte_data(client_ptr, udata->offset, val_lsb);
if (status==0) status = i2c_smbus_write_byte_data(client_ptr, udata->offset+1, val_hsb);
}
else
printk(KERN_ERR "PDDF_FAN: Doesn't support block FPGAI2C write yet");
}
else
printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname);
}

return status;
}


int sonic_i2c_get_fan_present_default(void *client, FAN_DATA_ATTR *udata, void *info)
{
Expand All @@ -341,6 +441,10 @@ int sonic_i2c_get_fan_present_default(void *client, FAN_DATA_ATTR *udata, void *
{
val = fan_cpld_client_read(udata);
}
else if (strcmp(udata->devtype, "fpgai2c") == 0)
{
val = fan_fpgai2c_client_read(udata);
}
else
{
val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset);
Expand All @@ -365,6 +469,10 @@ int sonic_i2c_get_fan_rpm_default(void *client, FAN_DATA_ATTR *udata, void *info
{
val = fan_cpld_client_read(udata);
}
else if (strcmp(udata->devtype, "fpgai2c") == 0)
{
val = fan_fpgai2c_client_read(udata);
}
else
{
if (udata->len == 1)
Expand Down Expand Up @@ -395,18 +503,26 @@ int sonic_i2c_get_fan_rpm_default(void *client, FAN_DATA_ATTR *udata, void *info
int sonic_i2c_get_fan_direction_default(void *client, FAN_DATA_ATTR *udata, void *info)
{
int status = 0;
uint32_t val = 0;
int val = 0;
struct fan_attr_info *painfo = (struct fan_attr_info *)info;

if (strcmp(udata->devtype, "cpld") == 0)
{
val = fan_cpld_client_read(udata);
}
else if (strcmp(udata->devtype, "fpgai2c") == 0)
{
val = fan_fpgai2c_client_read(udata);
}
else
{
val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset);
}
painfo->val.intval = ((val & udata->mask) == udata->cmpval);

if (val < 0)
status = val;
else
painfo->val.intval = ((val & udata->mask) == udata->cmpval);

return status;
}
Expand All @@ -415,7 +531,7 @@ int sonic_i2c_get_fan_direction_default(void *client, FAN_DATA_ATTR *udata, void
int sonic_i2c_set_fan_pwm_default(struct i2c_client *client, FAN_DATA_ATTR *udata, void *info)
{
int status = 0;
uint32_t val = 0;
int val = 0;
struct fan_attr_info *painfo = (struct fan_attr_info *)info;

val = painfo->val.intval & udata->mask;
Expand All @@ -427,52 +543,31 @@ int sonic_i2c_set_fan_pwm_default(struct i2c_client *client, FAN_DATA_ATTR *udat

if (strcmp(udata->devtype, "cpld") == 0)
{
if (udata->len==1)
{
status = board_i2c_cpld_write(udata->devaddr , udata->offset, val);
}
else
{
/* Get the I2C client for the CPLD */
struct i2c_client *client_ptr=NULL;
client_ptr = (struct i2c_client *)get_device_table(udata->devname);
if (client_ptr)
{
if (udata->len==2)
{
uint8_t val_lsb = val & 0xFF;
uint8_t val_hsb = (val >> 8) & 0xFF;
/* TODO: Check this logic for LE and BE */
i2c_smbus_write_byte_data(client, udata->offset, val_lsb);
i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb);
}
else
printk(KERN_ERR "PDDF_FAN: Doesn't support block CPLD write yet");
}
else
printk(KERN_ERR "Unable to get the client handle for %s\n", udata->devname);
}

status = fan_cpld_client_write(udata, val);
}
else if (strcmp(udata->devtype, "fpgai2c") == 0)
{
status = fan_fpgai2c_client_write(udata, val);
}
else
{
if (udata->len == 1)
i2c_smbus_write_byte_data(client, udata->offset, val);
status = i2c_smbus_write_byte_data(client, udata->offset, val);
else if (udata->len == 2)
{
uint8_t val_lsb = val & 0xFF;
uint8_t val_hsb = (val >> 8) & 0xFF;
/* TODO: Check this logic for LE and BE */
i2c_smbus_write_byte_data(client, udata->offset, val_lsb);
i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb);
status = i2c_smbus_write_byte_data(client, udata->offset, val_lsb);
if (status == 0) status = i2c_smbus_write_byte_data(client, udata->offset+1, val_hsb);
}
else
{
printk(KERN_DEBUG "%s: pwm should be of len 1/2 bytes. Not setting the pwm as the length is %d\n", __FUNCTION__, udata->len);
}
}
return status;

return status;
}


Expand All @@ -486,6 +581,10 @@ int sonic_i2c_get_fan_pwm_default(void *client, FAN_DATA_ATTR *udata, void *info
{
val = fan_cpld_client_read(udata);
}
else if (strcmp(udata->devtype, "fpgai2c") == 0)
{
val = fan_fpgai2c_client_read(udata);
}
else
{
if (udata->len == 1)
Expand Down Expand Up @@ -520,6 +619,10 @@ int sonic_i2c_get_fan_fault_default(void *client, FAN_DATA_ATTR *udata, void *in
{
val = fan_cpld_client_read(udata);
}
else if (strcmp(udata->devtype, "fpgai2c") == 0)
{
val = fan_fpgai2c_client_read(udata);
}
else
{
val = i2c_smbus_read_byte_data((struct i2c_client *)client, udata->offset);
Expand Down
2 changes: 2 additions & 0 deletions platform/pddf/i2c/modules/include/pddf_fan_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,6 @@ typedef struct FAN_PDATA
extern int board_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
extern int board_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);

extern int board_i2c_fpga_read(unsigned short cpld_addr, u8 reg);
extern int board_i2c_fpga_write(unsigned short cpld_addr, u8 reg, u8 value);
#endif
30 changes: 20 additions & 10 deletions platform/pddf/i2c/modules/include/pddf_led_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct kobject *cur_state_kobj=NULL;
* space JSON data file
*****************************************/
#define NAME_SIZE 32
#define VALUE_SIZE 5
typedef enum {
STATUS_LED_COLOR_GREEN,
STATUS_LED_COLOR_GREEN_BLINK,
Expand All @@ -42,20 +43,24 @@ typedef enum {
STATUS_LED_COLOR_AMBER_BLINK,
STATUS_LED_COLOR_BLUE,
STATUS_LED_COLOR_BLUE_BLINK,
STATUS_LED_COLOR_YELLOW,
STATUS_LED_COLOR_YELLOW_BLINK,
STATUS_LED_COLOR_OFF,
MAX_LED_STATUS
}LED_STATUS;

char* LED_STATUS_STR[] = {
"STATUS_LED_COLOR_GREEN",
"STATUS_LED_COLOR_GREEN_BLINK",
"STATUS_LED_COLOR_RED",
"STATUS_LED_COLOR_RED_BLINK",
"STATUS_LED_COLOR_AMBER",
"STATUS_LED_COLOR_AMBER_BLINK",
"STATUS_LED_COLOR_BLUE",
"STATUS_LED_COLOR_BLUE_BLINK",
"STATUS_LED_COLOR_OFF"
"green",
"green_blink",
"red",
"red_blink",
"amber",
"amber_blink",
"blue",
"blue_blink",
"yellow",
"yellow_blink",
"off"
};


Expand All @@ -71,7 +76,10 @@ typedef struct
int swpld_addr;
int swpld_addr_offset;
MASK_BITS bits;
unsigned short value;
u8 reg_values[VALUE_SIZE];
char value[NAME_SIZE];
char attr_devtype[NAME_SIZE];
char attr_devname[NAME_SIZE];
} LED_DATA;

typedef struct
Expand All @@ -88,6 +96,8 @@ typedef struct
LED_DATA data[MAX_LED_STATUS];
int swpld_addr;
int swpld_addr_offset;
char attr_devtype[NAME_SIZE];
char attr_devname[NAME_SIZE];
} LED_OPS_DATA;

typedef enum{
Expand Down
Loading

0 comments on commit 35f40c5

Please sign in to comment.