Skip to content

Commit

Permalink
RDMA/ocrdma: Query controller information
Browse files Browse the repository at this point in the history
Issue mailbox commands to query ocrdma controller information and phy
information and print them while adding ocrdma device.

Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
  • Loading branch information
Selvin Xavier authored and Roland Dreier committed Apr 3, 2014
1 parent bbc5ec5 commit a51f06e
Show file tree
Hide file tree
Showing 8 changed files with 1,135 additions and 2 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ocrdma/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ ccflags-y := -Idrivers/net/ethernet/emulex/benet

obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma.o

ocrdma-y := ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o
ocrdma-y := ocrdma_main.o ocrdma_verbs.o ocrdma_hw.o ocrdma_ah.o ocrdma_stats.o
61 changes: 61 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,17 @@
#define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
#define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"

#define OC_NAME_SH OCRDMA_NODE_DESC "(Skyhawk)"
#define OC_NAME_UNKNOWN OCRDMA_NODE_DESC "(Unknown)"

#define OC_SKH_DEVICE_PF 0x720
#define OC_SKH_DEVICE_VF 0x728
#define OCRDMA_MAX_AH 512

#define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)

#define convert_to_64bit(lo, hi) ((u64)hi << 32 | (u64)lo)

struct ocrdma_dev_attr {
u8 fw_ver[32];
u32 vendor_id;
Expand Down Expand Up @@ -86,6 +93,12 @@ struct ocrdma_dev_attr {
u8 num_ird_pages;
};

struct ocrdma_dma_mem {
void *va;
dma_addr_t pa;
u32 size;
};

struct ocrdma_pbl {
void *va;
dma_addr_t pa;
Expand Down Expand Up @@ -151,6 +164,26 @@ struct ocrdma_mr {
struct ocrdma_hw_mr hwmr;
};

struct ocrdma_stats {
u8 type;
struct ocrdma_dev *dev;
};

struct stats_mem {
struct ocrdma_mqe mqe;
void *va;
dma_addr_t pa;
u32 size;
char *debugfs_mem;
};

struct phy_info {
u16 auto_speeds_supported;
u16 fixed_speeds_supported;
u16 phy_type;
u16 interface_type;
};

struct ocrdma_dev {
struct ib_device ibdev;
struct ocrdma_dev_attr attr;
Expand Down Expand Up @@ -194,13 +227,30 @@ struct ocrdma_dev {
struct mqe_ctx mqe_ctx;

struct be_dev_info nic_info;
struct phy_info phy;
char model_number[32];
u32 hba_port_num;

struct list_head entry;
struct rcu_head rcu;
int id;
struct ocrdma_mr *stag_arr[OCRDMA_MAX_STAG];
u16 pvid;
u32 asic_id;

ulong last_stats_time;
struct mutex stats_lock; /* provide synch for debugfs operations */
struct stats_mem stats_mem;
struct ocrdma_stats rsrc_stats;
struct ocrdma_stats rx_stats;
struct ocrdma_stats wqe_stats;
struct ocrdma_stats tx_stats;
struct ocrdma_stats db_err_stats;
struct ocrdma_stats tx_qp_err_stats;
struct ocrdma_stats rx_qp_err_stats;
struct ocrdma_stats tx_dbg_stats;
struct ocrdma_stats rx_dbg_stats;
struct dentry *dir;
};

struct ocrdma_cq {
Expand Down Expand Up @@ -434,6 +484,17 @@ static inline int ocrdma_resolve_dmac(struct ocrdma_dev *dev,
return 0;
}

static inline char *hca_name(struct ocrdma_dev *dev)
{
switch (dev->nic_info.pdev->device) {
case OC_SKH_DEVICE_PF:
case OC_SKH_DEVICE_VF:
return OC_NAME_SH;
default:
return OC_NAME_UNKNOWN;
}
}

static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev,
int eqid)
{
Expand Down
148 changes: 148 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,23 @@ static int ocrdma_get_mbx_errno(u32 status)
return err_num;
}

char *port_speed_string(struct ocrdma_dev *dev)
{
char *str = "";
u16 speeds_supported;

speeds_supported = dev->phy.fixed_speeds_supported |
dev->phy.auto_speeds_supported;
if (speeds_supported & OCRDMA_PHY_SPEED_40GBPS)
str = "40Gbps ";
else if (speeds_supported & OCRDMA_PHY_SPEED_10GBPS)
str = "10Gbps ";
else if (speeds_supported & OCRDMA_PHY_SPEED_1GBPS)
str = "1Gbps ";

return str;
}

static int ocrdma_get_mbx_cqe_errno(u16 cqe_status)
{
int err_num = -EINVAL;
Expand Down Expand Up @@ -332,6 +349,11 @@ static void *ocrdma_init_emb_mqe(u8 opcode, u32 cmd_len)
return mqe;
}

static void *ocrdma_alloc_mqe(void)
{
return kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL);
}

static void ocrdma_free_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q)
{
dma_free_coherent(&dev->nic_info.pdev->dev, q->size, q->va, q->dma);
Expand Down Expand Up @@ -1154,6 +1176,96 @@ static int ocrdma_mbx_query_fw_config(struct ocrdma_dev *dev)
return status;
}

int ocrdma_mbx_rdma_stats(struct ocrdma_dev *dev, bool reset)
{
struct ocrdma_rdma_stats_req *req = dev->stats_mem.va;
struct ocrdma_mqe *mqe = &dev->stats_mem.mqe;
struct ocrdma_rdma_stats_resp *old_stats = NULL;
int status;

old_stats = kzalloc(sizeof(*old_stats), GFP_KERNEL);
if (old_stats == NULL)
return -ENOMEM;

memset(mqe, 0, sizeof(*mqe));
mqe->hdr.pyld_len = dev->stats_mem.size;
mqe->hdr.spcl_sge_cnt_emb |=
(1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
OCRDMA_MQE_HDR_SGE_CNT_MASK;
mqe->u.nonemb_req.sge[0].pa_lo = (u32) (dev->stats_mem.pa & 0xffffffff);
mqe->u.nonemb_req.sge[0].pa_hi = (u32) upper_32_bits(dev->stats_mem.pa);
mqe->u.nonemb_req.sge[0].len = dev->stats_mem.size;

/* Cache the old stats */
memcpy(old_stats, req, sizeof(struct ocrdma_rdma_stats_resp));
memset(req, 0, dev->stats_mem.size);

ocrdma_init_mch((struct ocrdma_mbx_hdr *)req,
OCRDMA_CMD_GET_RDMA_STATS,
OCRDMA_SUBSYS_ROCE,
dev->stats_mem.size);
if (reset)
req->reset_stats = reset;

status = ocrdma_nonemb_mbx_cmd(dev, mqe, dev->stats_mem.va);
if (status)
/* Copy from cache, if mbox fails */
memcpy(req, old_stats, sizeof(struct ocrdma_rdma_stats_resp));
else
ocrdma_le32_to_cpu(req, dev->stats_mem.size);

kfree(old_stats);
return status;
}

static int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev)
{
int status = -ENOMEM;
struct ocrdma_dma_mem dma;
struct ocrdma_mqe *mqe;
struct ocrdma_get_ctrl_attribs_rsp *ctrl_attr_rsp;
struct mgmt_hba_attribs *hba_attribs;

mqe = ocrdma_alloc_mqe();
if (!mqe)
return status;
memset(mqe, 0, sizeof(*mqe));

dma.size = sizeof(struct ocrdma_get_ctrl_attribs_rsp);
dma.va = dma_alloc_coherent(&dev->nic_info.pdev->dev,
dma.size, &dma.pa, GFP_KERNEL);
if (!dma.va)
goto free_mqe;

mqe->hdr.pyld_len = dma.size;
mqe->hdr.spcl_sge_cnt_emb |=
(1 << OCRDMA_MQE_HDR_SGE_CNT_SHIFT) &
OCRDMA_MQE_HDR_SGE_CNT_MASK;
mqe->u.nonemb_req.sge[0].pa_lo = (u32) (dma.pa & 0xffffffff);
mqe->u.nonemb_req.sge[0].pa_hi = (u32) upper_32_bits(dma.pa);
mqe->u.nonemb_req.sge[0].len = dma.size;

memset(dma.va, 0, dma.size);
ocrdma_init_mch((struct ocrdma_mbx_hdr *)dma.va,
OCRDMA_CMD_GET_CTRL_ATTRIBUTES,
OCRDMA_SUBSYS_COMMON,
dma.size);

status = ocrdma_nonemb_mbx_cmd(dev, mqe, dma.va);
if (!status) {
ctrl_attr_rsp = (struct ocrdma_get_ctrl_attribs_rsp *)dma.va;
hba_attribs = &ctrl_attr_rsp->ctrl_attribs.hba_attribs;

dev->hba_port_num = hba_attribs->phy_port;
strncpy(dev->model_number,
hba_attribs->controller_model_number, 31);
}
dma_free_coherent(&dev->nic_info.pdev->dev, dma.size, dma.va, dma.pa);
free_mqe:
kfree(mqe);
return status;
}

static int ocrdma_mbx_query_dev(struct ocrdma_dev *dev)
{
int status = -ENOMEM;
Expand Down Expand Up @@ -1201,6 +1313,35 @@ int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
return status;
}

static int ocrdma_mbx_get_phy_info(struct ocrdma_dev *dev)
{
int status = -ENOMEM;
struct ocrdma_mqe *cmd;
struct ocrdma_get_phy_info_rsp *rsp;

cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_PHY_DETAILS, sizeof(*cmd));
if (!cmd)
return status;

ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0],
OCRDMA_CMD_PHY_DETAILS, OCRDMA_SUBSYS_COMMON,
sizeof(*cmd));

status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
if (status)
goto mbx_err;

rsp = (struct ocrdma_get_phy_info_rsp *)cmd;
dev->phy.phy_type = le16_to_cpu(rsp->phy_type);
dev->phy.auto_speeds_supported =
le16_to_cpu(rsp->auto_speeds_supported);
dev->phy.fixed_speeds_supported =
le16_to_cpu(rsp->fixed_speeds_supported);
mbx_err:
kfree(cmd);
return status;
}

int ocrdma_mbx_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
{
int status = -ENOMEM;
Expand Down Expand Up @@ -2570,6 +2711,13 @@ int ocrdma_init_hw(struct ocrdma_dev *dev)
status = ocrdma_mbx_create_ah_tbl(dev);
if (status)
goto conf_err;
status = ocrdma_mbx_get_phy_info(dev);
if (status)
goto conf_err;
status = ocrdma_mbx_get_ctrl_attribs(dev);
if (status)
goto conf_err;

return 0;

conf_err:
Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,6 @@ bool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *, struct ocrdma_qp *);
void ocrdma_flush_qp(struct ocrdma_qp *);
int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);

int ocrdma_mbx_rdma_stats(struct ocrdma_dev *, bool reset);
char *port_speed_string(struct ocrdma_dev *dev);
#endif /* __OCRDMA_HW_H__ */
14 changes: 14 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "ocrdma_ah.h"
#include "be_roce.h"
#include "ocrdma_hw.h"
#include "ocrdma_stats.h"
#include "ocrdma_abi.h"

MODULE_VERSION(OCRDMA_ROCE_DRV_VERSION);
Expand Down Expand Up @@ -372,6 +373,15 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
spin_lock(&ocrdma_devlist_lock);
list_add_tail_rcu(&dev->entry, &ocrdma_dev_list);
spin_unlock(&ocrdma_devlist_lock);
/* Init stats */
ocrdma_add_port_stats(dev);

pr_info("%s %s: %s \"%s\" port %d\n",
dev_name(&dev->nic_info.pdev->dev), hca_name(dev),
port_speed_string(dev), dev->model_number,
dev->hba_port_num);
pr_info("%s ocrdma%d driver loaded successfully\n",
dev_name(&dev->nic_info.pdev->dev), dev->id);
return dev;

alloc_err:
Expand Down Expand Up @@ -400,6 +410,7 @@ static void ocrdma_remove(struct ocrdma_dev *dev)
/* first unregister with stack to stop all the active traffic
* of the registered clients.
*/
ocrdma_rem_port_stats(dev);
ib_unregister_device(&dev->ibdev);

spin_lock(&ocrdma_devlist_lock);
Expand Down Expand Up @@ -492,6 +503,8 @@ static int __init ocrdma_init_module(void)
{
int status;

ocrdma_init_debugfs();

status = register_inetaddr_notifier(&ocrdma_inetaddr_notifier);
if (status)
return status;
Expand All @@ -513,6 +526,7 @@ static void __exit ocrdma_exit_module(void)
{
be_roce_unregister_driver(&ocrdma_drv);
ocrdma_unregister_inet6addr_notifier();
ocrdma_rem_debugfs();
}

module_init(ocrdma_init_module);
Expand Down
Loading

0 comments on commit a51f06e

Please sign in to comment.