[PATCH v3] net/ncsi: Add NCSI OEM command support

Samuel Mendoza-Jonas sam at mendozajonas.com
Fri Oct 5 14:47:44 AEST 2018


On Wed, 2018-10-03 at 16:32 -0700, Vijay Khemka wrote:
> 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 at fb.com>

Reviewed-by: Samuel Mendoza-Jonas <sam at mendozajonas.com>

Technically this patch should also be marked [PATCH net-next] to target
David's next tree.

> ---
>  net/ncsi/internal.h |  5 +++++
>  net/ncsi/ncsi-cmd.c | 30 +++++++++++++++++++++++++++---
>  net/ncsi/ncsi-pkt.h | 14 ++++++++++++++
>  net/ncsi/ncsi-rsp.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 88 insertions(+), 4 deletions(-)
> 
> diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
> index 8055e3965cef..3d0a33b874f5 100644
> --- a/net/ncsi/internal.h
> +++ b/net/ncsi/internal.h
> @@ -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 */
> @@ -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;
> diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c
> index 7567ca63aae2..82b7d9201db8 100644
> --- a/net/ncsi/ncsi-cmd.c
> +++ b/net/ncsi/ncsi-cmd.c
> @@ -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;
> @@ -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 }
>  };
> @@ -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;
> diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
> index 91b4b66438df..0f2087c8d42a 100644
> --- a/net/ncsi/ncsi-pkt.h
> +++ b/net/ncsi/ncsi-pkt.h
> @@ -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   */
> diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
> index 930c1d3796f0..d66b34749027 100644
> --- a/net/ncsi/ncsi-rsp.c
> +++ b/net/ncsi/ncsi-rsp.c
> @@ -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;
> @@ -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  }
>  };




More information about the openbmc mailing list