Skip to content

Commit

Permalink
pds_core: add devcmd device interfaces
Browse files Browse the repository at this point in the history
The devcmd interface is the basic connection to the device through the
PCI BAR for low level identification and command services.  This does
the early device initialization and finds the identity data, and adds
devcmd routines to be used by later driver bits.

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shannon Nelson authored and David S. Miller committed Apr 21, 2023
1 parent 55435ea commit 523847d
Show file tree
Hide file tree
Showing 8 changed files with 699 additions and 3 deletions.
4 changes: 3 additions & 1 deletion drivers/net/ethernet/amd/pds_core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

obj-$(CONFIG_PDS_CORE) := pds_core.o

pds_core-y := main.o
pds_core-y := main.o \
dev.o \
core.o

pds_core-$(CONFIG_DEBUG_FS) += debugfs.o
36 changes: 36 additions & 0 deletions drivers/net/ethernet/amd/pds_core/core.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2023 Advanced Micro Devices, Inc */

#include "core.h"

int pdsc_setup(struct pdsc *pdsc, bool init)
{
int err = 0;

if (init)
err = pdsc_dev_init(pdsc);
else
err = pdsc_dev_reinit(pdsc);
if (err)
return err;

clear_bit(PDSC_S_FW_DEAD, &pdsc->state);
return 0;
}

void pdsc_teardown(struct pdsc *pdsc, bool removing)
{
pdsc_devcmd_reset(pdsc);

if (removing) {
kfree(pdsc->intr_info);
pdsc->intr_info = NULL;
}

if (pdsc->kern_dbpage) {
iounmap(pdsc->kern_dbpage);
pdsc->kern_dbpage = NULL;
}

set_bit(PDSC_S_FW_DEAD, &pdsc->state);
}
50 changes: 50 additions & 0 deletions drivers/net/ethernet/amd/pds_core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@

#include <linux/pds/pds_common.h>
#include <linux/pds/pds_core_if.h>
#include <linux/pds/pds_intr.h>

#define PDSC_DRV_DESCRIPTION "AMD/Pensando Core Driver"
#define PDSC_TEARDOWN_RECOVERY false
#define PDSC_TEARDOWN_REMOVING true
#define PDSC_SETUP_RECOVERY false
#define PDSC_SETUP_INIT true

struct pdsc_dev_bar {
void __iomem *vaddr;
Expand All @@ -19,6 +24,22 @@ struct pdsc_dev_bar {
int res_index;
};

struct pdsc_devinfo {
u8 asic_type;
u8 asic_rev;
char fw_version[PDS_CORE_DEVINFO_FWVERS_BUFLEN + 1];
char serial_num[PDS_CORE_DEVINFO_SERIAL_BUFLEN + 1];
};

#define PDSC_INTR_NAME_MAX_SZ 32

struct pdsc_intr_info {
char name[PDSC_INTR_NAME_MAX_SZ];
unsigned int index;
unsigned int vector;
void *data;
};

/* No state flags set means we are in a steady running state */
enum pdsc_state_flags {
PDSC_S_FW_DEAD, /* stopped, wait on startup or recovery */
Expand All @@ -38,7 +59,19 @@ struct pdsc {
int uid;

unsigned long state;
u8 fw_status;
u8 fw_generation;
unsigned long last_fw_time;
u32 last_hb;

struct pdsc_devinfo dev_info;
struct pds_core_dev_identity dev_ident;
unsigned int nintrs;
struct pdsc_intr_info *intr_info; /* array of nintrs elements */

unsigned int devcmd_timeout;
struct mutex devcmd_lock; /* lock for dev_cmd operations */
struct mutex config_lock; /* lock for configuration operations */
struct pds_core_dev_info_regs __iomem *info_regs;
struct pds_core_dev_cmd_regs __iomem *cmd_regs;
struct pds_core_intr __iomem *intr_ctrl;
Expand All @@ -52,5 +85,22 @@ void pdsc_debugfs_create(void);
void pdsc_debugfs_destroy(void);
void pdsc_debugfs_add_dev(struct pdsc *pdsc);
void pdsc_debugfs_del_dev(struct pdsc *pdsc);
void pdsc_debugfs_add_ident(struct pdsc *pdsc);
void pdsc_debugfs_add_irqs(struct pdsc *pdsc);

int pdsc_err_to_errno(enum pds_core_status_code code);
bool pdsc_is_fw_running(struct pdsc *pdsc);
bool pdsc_is_fw_good(struct pdsc *pdsc);
int pdsc_devcmd(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
union pds_core_dev_comp *comp, int max_seconds);
int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
union pds_core_dev_comp *comp, int max_seconds);
int pdsc_devcmd_init(struct pdsc *pdsc);
int pdsc_devcmd_reset(struct pdsc *pdsc);
int pdsc_dev_reinit(struct pdsc *pdsc);
int pdsc_dev_init(struct pdsc *pdsc);

int pdsc_setup(struct pdsc *pdsc, bool init);
void pdsc_teardown(struct pdsc *pdsc, bool removing);

#endif /* _PDSC_H_ */
38 changes: 38 additions & 0 deletions drivers/net/ethernet/amd/pds_core/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,41 @@ void pdsc_debugfs_del_dev(struct pdsc *pdsc)
debugfs_remove_recursive(pdsc->dentry);
pdsc->dentry = NULL;
}

static int identity_show(struct seq_file *seq, void *v)
{
struct pdsc *pdsc = seq->private;
struct pds_core_dev_identity *ident;
int vt;

ident = &pdsc->dev_ident;

seq_printf(seq, "fw_heartbeat: 0x%x\n",
ioread32(&pdsc->info_regs->fw_heartbeat));

seq_printf(seq, "nlifs: %d\n",
le32_to_cpu(ident->nlifs));
seq_printf(seq, "nintrs: %d\n",
le32_to_cpu(ident->nintrs));
seq_printf(seq, "ndbpgs_per_lif: %d\n",
le32_to_cpu(ident->ndbpgs_per_lif));
seq_printf(seq, "intr_coal_mult: %d\n",
le32_to_cpu(ident->intr_coal_mult));
seq_printf(seq, "intr_coal_div: %d\n",
le32_to_cpu(ident->intr_coal_div));

seq_puts(seq, "vif_types: ");
for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++)
seq_printf(seq, "%d ",
le16_to_cpu(pdsc->dev_ident.vif_types[vt]));
seq_puts(seq, "\n");

return 0;
}
DEFINE_SHOW_ATTRIBUTE(identity);

void pdsc_debugfs_add_ident(struct pdsc *pdsc)
{
debugfs_create_file("identity", 0400, pdsc->dentry,
pdsc, &identity_fops);
}
Loading

0 comments on commit 523847d

Please sign in to comment.