Commit 8d6198a1 authored by Shinas Rasheed's avatar Shinas Rasheed Committed by David S. Miller
Browse files

octeon_ep: support to fetch firmware info



Add support to fetch firmware info such as heartbeat miss count,
heartbeat interval. This shall be used for heartbeat monitor.

Signed-off-by: default avatarShinas Rasheed <srasheed@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d692873c
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@
#define CTRL_MBOX_MAX_PF	128
#define CTRL_MBOX_SZ		((size_t)(0x400000 / CTRL_MBOX_MAX_PF))

#define FW_HB_INTERVAL_IN_SECS		1
#define FW_HB_MISS_COUNT		10

/* Names of Hardware non-queue generic interrupts */
static char *cn93_non_ioq_msix_names[] = {
	"epf_ire_rint",
@@ -250,12 +247,11 @@ static void octep_init_config_cn93_pf(struct octep_device *oct)
		link = PCI_DEVFN(PCI_SLOT(oct->pdev->devfn), link);
	}
	conf->ctrl_mbox_cfg.barmem_addr = (void __iomem *)oct->mmio[2].hw_addr +
					   (0x400000ull * 7) +
					   CN93_PEM_BAR4_INDEX_OFFSET +
					   (link * CTRL_MBOX_SZ);

	conf->hb_interval = FW_HB_INTERVAL_IN_SECS;
	conf->max_hb_miss_cnt = FW_HB_MISS_COUNT;

	conf->fw_info.hb_interval = OCTEP_DEFAULT_FW_HB_INTERVAL;
	conf->fw_info.hb_miss_count = OCTEP_DEFAULT_FW_HB_MISS_COUNT;
}

/* Setup registers for a hardware Tx Queue  */
+17 −5
Original line number Diff line number Diff line
@@ -49,6 +49,11 @@
/* Default MTU */
#define OCTEP_DEFAULT_MTU    1500

/* pf heartbeat interval in milliseconds */
#define OCTEP_DEFAULT_FW_HB_INTERVAL           1000
/* pf heartbeat miss count */
#define OCTEP_DEFAULT_FW_HB_MISS_COUNT         20

/* Macros to get octeon config params */
#define CFG_GET_IQ_CFG(cfg)             ((cfg)->iq)
#define CFG_GET_IQ_NUM_DESC(cfg)        ((cfg)->iq.num_descs)
@@ -181,6 +186,16 @@ struct octep_ctrl_mbox_config {
	void __iomem *barmem_addr;
};

/* Info from firmware */
struct octep_fw_info {
	/* interface pkind */
	u16 pkind;
	/* heartbeat interval in milliseconds */
	u16 hb_interval;
	/* heartbeat miss count */
	u16 hb_miss_count;
};

/* Data Structure to hold configuration limits and active config */
struct octep_config {
	/* Input Queue attributes. */
@@ -201,10 +216,7 @@ struct octep_config {
	/* ctrl mbox config */
	struct octep_ctrl_mbox_config ctrl_mbox_cfg;

	/* Configured maximum heartbeat miss count */
	u32 max_hb_miss_cnt;

	/* Configured firmware heartbeat interval in secs */
	u32 hb_interval;
	/* fw info */
	struct octep_fw_info fw_info;
};
#endif /* _OCTEP_CONFIG_H_ */
+23 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ static atomic_t ctrl_net_msg_id;

/* Control plane version in which OCTEP_CTRL_NET_H2F_CMD was added */
static const u32 octep_ctrl_net_h2f_cmd_versions[OCTEP_CTRL_NET_H2F_CMD_MAX] = {
	[OCTEP_CTRL_NET_H2F_CMD_INVALID ... OCTEP_CTRL_NET_H2F_CMD_LINK_INFO] =
	[OCTEP_CTRL_NET_H2F_CMD_INVALID ... OCTEP_CTRL_NET_H2F_CMD_GET_INFO] =
	 OCTEP_CP_VERSION(1, 0, 0)
};

@@ -353,6 +353,28 @@ void octep_ctrl_net_recv_fw_messages(struct octep_device *oct)
	}
}

int octep_ctrl_net_get_info(struct octep_device *oct, int vfid,
			    struct octep_fw_info *info)
{
	struct octep_ctrl_net_wait_data d = {0};
	struct octep_ctrl_net_h2f_resp *resp;
	struct octep_ctrl_net_h2f_req *req;
	int err;

	req = &d.data.req;
	init_send_req(&d.msg, req, 0, vfid);
	req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_INFO;
	req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET;
	err = octep_send_mbox_req(oct, &d, true);
	if (err < 0)
		return err;

	resp = &d.data.resp;
	memcpy(info, &resp->info.fw_info, sizeof(struct octep_fw_info));

	return 0;
}

int octep_ctrl_net_uninit(struct octep_device *oct)
{
	struct octep_ctrl_net_wait_data *pos, *n;
+18 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ enum octep_ctrl_net_h2f_cmd {
	OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS,
	OCTEP_CTRL_NET_H2F_CMD_RX_STATE,
	OCTEP_CTRL_NET_H2F_CMD_LINK_INFO,
	OCTEP_CTRL_NET_H2F_CMD_GET_INFO,
	OCTEP_CTRL_NET_H2F_CMD_MAX
};

@@ -161,6 +162,11 @@ struct octep_ctrl_net_h2f_resp_cmd_state {
	u16 state;
};

/* get info request */
struct octep_ctrl_net_h2f_resp_cmd_get_info {
	struct octep_fw_info fw_info;
};

/* Host to fw response data */
struct octep_ctrl_net_h2f_resp {
	union octep_ctrl_net_resp_hdr hdr;
@@ -171,6 +177,7 @@ struct octep_ctrl_net_h2f_resp {
		struct octep_ctrl_net_h2f_resp_cmd_state link;
		struct octep_ctrl_net_h2f_resp_cmd_state rx;
		struct octep_ctrl_net_link_info link_info;
		struct octep_ctrl_net_h2f_resp_cmd_get_info info;
	};
} __packed;

@@ -330,6 +337,17 @@ int octep_ctrl_net_set_link_info(struct octep_device *oct,
 */
void octep_ctrl_net_recv_fw_messages(struct octep_device *oct);

/** Get info from firmware.
 *
 * @param oct: non-null pointer to struct octep_device.
 * @param vfid: Index of virtual function.
 * @param info: non-null pointer to struct octep_fw_info.
 *
 * return value: 0 on success, -errno on failure.
 */
int octep_ctrl_net_get_info(struct octep_device *oct, int vfid,
			    struct octep_fw_info *info);

/** Uninitialize data for ctrl net.
 *
 * @param oct: non-null pointer to struct octep_device.
+12 −4
Original line number Diff line number Diff line
@@ -918,9 +918,9 @@ static void octep_hb_timeout_task(struct work_struct *work)
	int miss_cnt;

	miss_cnt = atomic_inc_return(&oct->hb_miss_cnt);
	if (miss_cnt < oct->conf->max_hb_miss_cnt) {
	if (miss_cnt < oct->conf->fw_info.hb_miss_count) {
		queue_delayed_work(octep_wq, &oct->hb_task,
				   msecs_to_jiffies(oct->conf->hb_interval * 1000));
				   msecs_to_jiffies(oct->conf->fw_info.hb_interval));
		return;
	}

@@ -1013,8 +1013,7 @@ int octep_device_setup(struct octep_device *oct)

	atomic_set(&oct->hb_miss_cnt, 0);
	INIT_DELAYED_WORK(&oct->hb_task, octep_hb_timeout_task);
	queue_delayed_work(octep_wq, &oct->hb_task,
			   msecs_to_jiffies(oct->conf->hb_interval * 1000));

	return 0;

unsupported_dev:
@@ -1143,6 +1142,15 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
		dev_err(&pdev->dev, "Device setup failed\n");
		goto err_octep_config;
	}

	octep_ctrl_net_get_info(octep_dev, OCTEP_CTRL_NET_INVALID_VFID,
				&octep_dev->conf->fw_info);
	dev_info(&octep_dev->pdev->dev, "Heartbeat interval %u msecs Heartbeat miss count %u\n",
		 octep_dev->conf->fw_info.hb_interval,
		 octep_dev->conf->fw_info.hb_miss_count);
	queue_delayed_work(octep_wq, &octep_dev->hb_task,
			   msecs_to_jiffies(octep_dev->conf->fw_info.hb_interval));

	INIT_WORK(&octep_dev->tx_timeout_task, octep_tx_timeout_task);
	INIT_WORK(&octep_dev->ctrl_mbox_task, octep_ctrl_mbox_task);
	INIT_DELAYED_WORK(&octep_dev->intr_poll_task, octep_intr_poll_task);
Loading