Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a51f06e1 authored by Selvin Xavier's avatar Selvin Xavier Committed by Roland Dreier
Browse files

RDMA/ocrdma: Query controller information



Issue mailbox commands to query ocrdma controller information and phy
information and print them while adding ocrdma device.

Signed-off-by: default avatarSelvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: default avatarDevesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent bbc5ec52
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -194,6 +227,9 @@ 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;
@@ -201,6 +237,20 @@ struct ocrdma_dev {
	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 {
@@ -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)
{
+148 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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;
@@ -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;
@@ -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:
+2 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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:
@@ -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);
@@ -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;
@@ -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);
Loading