Commit a20b4c5f authored by Sathesh Edara's avatar Sathesh Edara Committed by David S. Miller

octeon_ep: Add control plane host and firmware versions.

Implement control plane mailbox versions for host and firmware.
Versions are published in info area of control mailbox bar4
memory structure.Firmware will publish minimum and maximum
supported versions.Control plane mailbox apis will check for
firmware version before sending any control commands to firmware.
Notifications from firmware will similarly be checked for host
version compatibility.
Signed-off-by: default avatarSathesh Edara <sedara@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 12aa0a3b
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2022 Marvell.
*/
#ifndef __OCTEP_CP_VERSION_H__
#define __OCTEP_CP_VERSION_H__
#define OCTEP_CP_VERSION(a, b, c) ((((a) & 0xff) << 16) + \
(((b) & 0xff) << 8) + \
((c) & 0xff))
#endif /* __OCTEP_CP_VERSION_H__ */
...@@ -37,7 +37,9 @@ ...@@ -37,7 +37,9 @@
#define OCTEP_CTRL_MBOX_INFO_MAGIC_NUM(m) (m) #define OCTEP_CTRL_MBOX_INFO_MAGIC_NUM(m) (m)
#define OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(m) ((m) + 8) #define OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(m) ((m) + 8)
#define OCTEP_CTRL_MBOX_INFO_HOST_VERSION(m) ((m) + 16)
#define OCTEP_CTRL_MBOX_INFO_HOST_STATUS(m) ((m) + 24) #define OCTEP_CTRL_MBOX_INFO_HOST_STATUS(m) ((m) + 24)
#define OCTEP_CTRL_MBOX_INFO_FW_VERSION(m) ((m) + 136)
#define OCTEP_CTRL_MBOX_INFO_FW_STATUS(m) ((m) + 144) #define OCTEP_CTRL_MBOX_INFO_FW_STATUS(m) ((m) + 144)
#define OCTEP_CTRL_MBOX_H2FQ_INFO(m) ((m) + OCTEP_CTRL_MBOX_INFO_SZ) #define OCTEP_CTRL_MBOX_H2FQ_INFO(m) ((m) + OCTEP_CTRL_MBOX_INFO_SZ)
...@@ -71,7 +73,7 @@ static u32 octep_ctrl_mbox_circq_depth(u32 pi, u32 ci, u32 sz) ...@@ -71,7 +73,7 @@ static u32 octep_ctrl_mbox_circq_depth(u32 pi, u32 ci, u32 sz)
int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox) int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)
{ {
u64 magic_num, status; u64 magic_num, status, fw_versions;
if (!mbox) if (!mbox)
return -EINVAL; return -EINVAL;
...@@ -93,6 +95,9 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox) ...@@ -93,6 +95,9 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)
return -EINVAL; return -EINVAL;
} }
fw_versions = readq(OCTEP_CTRL_MBOX_INFO_FW_VERSION(mbox->barmem));
mbox->min_fw_version = ((fw_versions & 0xffffffff00000000ull) >> 32);
mbox->max_fw_version = (fw_versions & 0xffffffff);
mbox->barmem_sz = readl(OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(mbox->barmem)); mbox->barmem_sz = readl(OCTEP_CTRL_MBOX_INFO_BARMEM_SZ(mbox->barmem));
writeq(OCTEP_CTRL_MBOX_STATUS_INIT, writeq(OCTEP_CTRL_MBOX_STATUS_INIT,
...@@ -113,6 +118,7 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox) ...@@ -113,6 +118,7 @@ int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox)
OCTEP_CTRL_MBOX_TOTAL_INFO_SZ + OCTEP_CTRL_MBOX_TOTAL_INFO_SZ +
mbox->h2fq.sz; mbox->h2fq.sz;
writeq(mbox->version, OCTEP_CTRL_MBOX_INFO_HOST_VERSION(mbox->barmem));
/* ensure ready state is seen after everything is initialized */ /* ensure ready state is seen after everything is initialized */
wmb(); wmb();
writeq(OCTEP_CTRL_MBOX_STATUS_READY, writeq(OCTEP_CTRL_MBOX_STATUS_READY,
...@@ -258,6 +264,7 @@ int octep_ctrl_mbox_uninit(struct octep_ctrl_mbox *mbox) ...@@ -258,6 +264,7 @@ int octep_ctrl_mbox_uninit(struct octep_ctrl_mbox *mbox)
if (!mbox->barmem) if (!mbox->barmem)
return -EINVAL; return -EINVAL;
writeq(0, OCTEP_CTRL_MBOX_INFO_HOST_VERSION(mbox->barmem));
writeq(OCTEP_CTRL_MBOX_STATUS_INVALID, writeq(OCTEP_CTRL_MBOX_STATUS_INVALID,
OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem)); OCTEP_CTRL_MBOX_INFO_HOST_STATUS(mbox->barmem));
/* ensure uninit state is written before uninitialization */ /* ensure uninit state is written before uninitialization */
......
...@@ -121,6 +121,8 @@ struct octep_ctrl_mbox_q { ...@@ -121,6 +121,8 @@ struct octep_ctrl_mbox_q {
}; };
struct octep_ctrl_mbox { struct octep_ctrl_mbox {
/* control plane version */
u64 version;
/* size of bar memory */ /* size of bar memory */
u32 barmem_sz; u32 barmem_sz;
/* pointer to BAR memory */ /* pointer to BAR memory */
...@@ -133,6 +135,10 @@ struct octep_ctrl_mbox { ...@@ -133,6 +135,10 @@ struct octep_ctrl_mbox {
struct mutex h2fq_lock; struct mutex h2fq_lock;
/* lock for f2hq */ /* lock for f2hq */
struct mutex f2hq_lock; struct mutex f2hq_lock;
/* Min control plane version supported by firmware */
u32 min_fw_version;
/* Max control plane version supported by firmware */
u32 max_fw_version;
}; };
/* Initialize control mbox. /* Initialize control mbox.
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#include "octep_main.h" #include "octep_main.h"
#include "octep_ctrl_net.h" #include "octep_ctrl_net.h"
/* Control plane version */
#define OCTEP_CP_VERSION_CURRENT OCTEP_CP_VERSION(1, 0, 0)
static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr); static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr);
static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu); static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu);
static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac); static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac);
...@@ -21,6 +24,18 @@ static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state); ...@@ -21,6 +24,18 @@ static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state);
static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info); static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info);
static atomic_t ctrl_net_msg_id; 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_CP_VERSION(1, 0, 0)
};
/* Control plane version in which OCTEP_CTRL_NET_F2H_CMD was added */
static const u32 octep_ctrl_net_f2h_cmd_versions[OCTEP_CTRL_NET_F2H_CMD_MAX] = {
[OCTEP_CTRL_NET_F2H_CMD_INVALID ... OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS] =
OCTEP_CP_VERSION(1, 0, 0)
};
static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf, static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf,
u16 sz, int vfid) u16 sz, int vfid)
{ {
...@@ -41,7 +56,13 @@ static int octep_send_mbox_req(struct octep_device *oct, ...@@ -41,7 +56,13 @@ static int octep_send_mbox_req(struct octep_device *oct,
struct octep_ctrl_net_wait_data *d, struct octep_ctrl_net_wait_data *d,
bool wait_for_response) bool wait_for_response)
{ {
int err, ret; int err, ret, cmd;
/* check if firmware is compatible for this request */
cmd = d->data.req.hdr.s.cmd;
if (octep_ctrl_net_h2f_cmd_versions[cmd] > oct->ctrl_mbox.max_fw_version ||
octep_ctrl_net_h2f_cmd_versions[cmd] < oct->ctrl_mbox.min_fw_version)
return -EOPNOTSUPP;
err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg); err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg);
if (err < 0) if (err < 0)
...@@ -84,12 +105,16 @@ int octep_ctrl_net_init(struct octep_device *oct) ...@@ -84,12 +105,16 @@ int octep_ctrl_net_init(struct octep_device *oct)
/* Initialize control mbox */ /* Initialize control mbox */
ctrl_mbox = &oct->ctrl_mbox; ctrl_mbox = &oct->ctrl_mbox;
ctrl_mbox->version = OCTEP_CP_VERSION_CURRENT;
ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf); ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf);
ret = octep_ctrl_mbox_init(ctrl_mbox); ret = octep_ctrl_mbox_init(ctrl_mbox);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to initialize control mbox\n"); dev_err(&pdev->dev, "Failed to initialize control mbox\n");
return ret; return ret;
} }
dev_info(&pdev->dev, "Control plane versions host: %llx, firmware: %x:%x\n",
ctrl_mbox->version, ctrl_mbox->min_fw_version,
ctrl_mbox->max_fw_version);
oct->ctrl_mbox_ifstats_offset = ctrl_mbox->barmem_sz; oct->ctrl_mbox_ifstats_offset = ctrl_mbox->barmem_sz;
return 0; return 0;
...@@ -273,9 +298,17 @@ static int process_mbox_notify(struct octep_device *oct, ...@@ -273,9 +298,17 @@ static int process_mbox_notify(struct octep_device *oct,
{ {
struct net_device *netdev = oct->netdev; struct net_device *netdev = oct->netdev;
struct octep_ctrl_net_f2h_req *req; struct octep_ctrl_net_f2h_req *req;
int cmd;
req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg; req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg;
switch (req->hdr.s.cmd) { cmd = req->hdr.s.cmd;
/* check if we support this command */
if (octep_ctrl_net_f2h_cmd_versions[cmd] > OCTEP_CP_VERSION_CURRENT ||
octep_ctrl_net_f2h_cmd_versions[cmd] < OCTEP_CP_VERSION_CURRENT)
return -EOPNOTSUPP;
switch (cmd) {
case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS: case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS:
if (netif_running(netdev)) { if (netif_running(netdev)) {
if (req->link.state) { if (req->link.state) {
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef __OCTEP_CTRL_NET_H__ #ifndef __OCTEP_CTRL_NET_H__
#define __OCTEP_CTRL_NET_H__ #define __OCTEP_CTRL_NET_H__
#include "octep_cp_version.h"
#define OCTEP_CTRL_NET_INVALID_VFID (-1) #define OCTEP_CTRL_NET_INVALID_VFID (-1)
/* Supported commands */ /* Supported commands */
...@@ -39,12 +41,14 @@ enum octep_ctrl_net_h2f_cmd { ...@@ -39,12 +41,14 @@ enum octep_ctrl_net_h2f_cmd {
OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS, OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS,
OCTEP_CTRL_NET_H2F_CMD_RX_STATE, OCTEP_CTRL_NET_H2F_CMD_RX_STATE,
OCTEP_CTRL_NET_H2F_CMD_LINK_INFO, OCTEP_CTRL_NET_H2F_CMD_LINK_INFO,
OCTEP_CTRL_NET_H2F_CMD_MAX
}; };
/* Supported fw to host commands */ /* Supported fw to host commands */
enum octep_ctrl_net_f2h_cmd { enum octep_ctrl_net_f2h_cmd {
OCTEP_CTRL_NET_F2H_CMD_INVALID = 0, OCTEP_CTRL_NET_F2H_CMD_INVALID = 0,
OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS, OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS,
OCTEP_CTRL_NET_F2H_CMD_MAX
}; };
union octep_ctrl_net_req_hdr { union octep_ctrl_net_req_hdr {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment