Skip to content

Commit

Permalink
net/ncsi: Add NCSI OEM command support
Browse files Browse the repository at this point in the history
This patch adds OEM commands and response handling. It also defines OEM
command and response structure as per NCSI specification along with its
handlers.

ncsi_cmd_handler_oem: This is a generic command request handler for OEM
commands
ncsi_rsp_handler_oem: This is a generic response handler for OEM commands

Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Reviewed-by: Justin Lee <justin.lee1@dell.com>
Reviewed-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vijay Khemka authored and David S. Miller committed Oct 5, 2018
1 parent 6f84749 commit fb4ee67
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
5 changes: 5 additions & 0 deletions net/ncsi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ enum {
NCSI_MODE_MAX
};

/* OEM Vendor Manufacture ID */
#define NCSI_OEM_MFR_MLX_ID 0x8119
#define NCSI_OEM_MFR_BCM_ID 0x113d

struct ncsi_channel_version {
u32 version; /* Supported BCD encoded NCSI version */
u32 alpha2; /* Supported BCD encoded NCSI version */
Expand Down Expand Up @@ -305,6 +309,7 @@ struct ncsi_cmd_arg {
unsigned short words[8];
unsigned int dwords[4];
};
unsigned char *data; /* NCSI OEM data */
};

extern struct list_head ncsi_dev_list;
Expand Down
30 changes: 27 additions & 3 deletions net/ncsi/ncsi-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,25 @@ static int ncsi_cmd_handler_snfc(struct sk_buff *skb,
return 0;
}

static int ncsi_cmd_handler_oem(struct sk_buff *skb,
struct ncsi_cmd_arg *nca)
{
struct ncsi_cmd_oem_pkt *cmd;
unsigned int len;

len = sizeof(struct ncsi_cmd_pkt_hdr) + 4;
if (nca->payload < 26)
len += 26;
else
len += nca->payload;

cmd = skb_put_zero(skb, len);
memcpy(&cmd->mfr_id, nca->data, nca->payload);
ncsi_cmd_build_header(&cmd->cmd.common, nca);

return 0;
}

static struct ncsi_cmd_handler {
unsigned char type;
int payload;
Expand Down Expand Up @@ -244,7 +263,7 @@ static struct ncsi_cmd_handler {
{ NCSI_PKT_CMD_GNS, 0, ncsi_cmd_handler_default },
{ NCSI_PKT_CMD_GNPTS, 0, ncsi_cmd_handler_default },
{ NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default },
{ NCSI_PKT_CMD_OEM, 0, NULL },
{ NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem },
{ NCSI_PKT_CMD_PLDM, 0, NULL },
{ NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }
};
Expand Down Expand Up @@ -316,8 +335,13 @@ int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
return -ENOENT;
}

/* Get packet payload length and allocate the request */
nca->payload = nch->payload;
/* Get packet payload length and allocate the request
* It is expected that if length set as negative in
* handler structure means caller is initializing it
* and setting length in nca before calling xmit function
*/
if (nch->payload >= 0)
nca->payload = nch->payload;
nr = ncsi_alloc_command(nca);
if (!nr)
return -ENOMEM;
Expand Down
14 changes: 14 additions & 0 deletions net/ncsi/ncsi-pkt.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,20 @@ struct ncsi_cmd_snfc_pkt {
unsigned char pad[22];
};

/* OEM Request Command as per NCSI Specification */
struct ncsi_cmd_oem_pkt {
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
__be32 mfr_id; /* Manufacture ID */
unsigned char data[]; /* OEM Payload Data */
};

/* OEM Response Packet as per NCSI Specification */
struct ncsi_rsp_oem_pkt {
struct ncsi_rsp_pkt_hdr rsp; /* Command header */
__be32 mfr_id; /* Manufacture ID */
unsigned char data[]; /* Payload data */
};

/* Get Link Status */
struct ncsi_rsp_gls_pkt {
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
Expand Down
43 changes: 42 additions & 1 deletion net/ncsi/ncsi-rsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,47 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
return 0;
}

static struct ncsi_rsp_oem_handler {
unsigned int mfr_id;
int (*handler)(struct ncsi_request *nr);
} ncsi_rsp_oem_handlers[] = {
{ NCSI_OEM_MFR_MLX_ID, NULL },
{ NCSI_OEM_MFR_BCM_ID, NULL }
};

/* Response handler for OEM command */
static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
{
struct ncsi_rsp_oem_pkt *rsp;
struct ncsi_rsp_oem_handler *nrh = NULL;
unsigned int mfr_id, i;

/* Get the response header */
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
mfr_id = ntohl(rsp->mfr_id);

/* Check for manufacturer id and Find the handler */
for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
if (ncsi_rsp_oem_handlers[i].handler)
nrh = &ncsi_rsp_oem_handlers[i];
else
nrh = NULL;

break;
}
}

if (!nrh) {
netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
mfr_id);
return -ENOENT;
}

/* Process the packet */
return nrh->handler(nr);
}

static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
{
struct ncsi_rsp_gvi_pkt *rsp;
Expand Down Expand Up @@ -932,7 +973,7 @@ static struct ncsi_rsp_handler {
{ NCSI_PKT_RSP_GNS, 172, ncsi_rsp_handler_gns },
{ NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts },
{ NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
{ NCSI_PKT_RSP_OEM, 0, NULL },
{ NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
{ NCSI_PKT_RSP_PLDM, 0, NULL },
{ NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }
};
Expand Down

0 comments on commit fb4ee67

Please sign in to comment.