aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijay Khemka <vijaykhemka@fb.com>2018-10-05 13:46:01 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-05 17:54:47 -0400
commitfb4ee67529ff3e4c5874768477887c2df5714c96 (patch)
treebf3176bd5f28d89058a23f3b88ebdf165bd1dad5
parent6f8474922b443fd4a89a5dd5b891a3c6a144b9c7 (diff)
net/ncsi: Add NCSI OEM command support
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>
-rw-r--r--net/ncsi/internal.h5
-rw-r--r--net/ncsi/ncsi-cmd.c30
-rw-r--r--net/ncsi/ncsi-pkt.h14
-rw-r--r--net/ncsi/ncsi-rsp.c43
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 {
68 NCSI_MODE_MAX 68 NCSI_MODE_MAX
69}; 69};
70 70
71/* OEM Vendor Manufacture ID */
72#define NCSI_OEM_MFR_MLX_ID 0x8119
73#define NCSI_OEM_MFR_BCM_ID 0x113d
74
71struct ncsi_channel_version { 75struct ncsi_channel_version {
72 u32 version; /* Supported BCD encoded NCSI version */ 76 u32 version; /* Supported BCD encoded NCSI version */
73 u32 alpha2; /* Supported BCD encoded NCSI version */ 77 u32 alpha2; /* Supported BCD encoded NCSI version */
@@ -305,6 +309,7 @@ struct ncsi_cmd_arg {
305 unsigned short words[8]; 309 unsigned short words[8];
306 unsigned int dwords[4]; 310 unsigned int dwords[4];
307 }; 311 };
312 unsigned char *data; /* NCSI OEM data */
308}; 313};
309 314
310extern struct list_head ncsi_dev_list; 315extern 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,
211 return 0; 211 return 0;
212} 212}
213 213
214static int ncsi_cmd_handler_oem(struct sk_buff *skb,
215 struct ncsi_cmd_arg *nca)
216{
217 struct ncsi_cmd_oem_pkt *cmd;
218 unsigned int len;
219
220 len = sizeof(struct ncsi_cmd_pkt_hdr) + 4;
221 if (nca->payload < 26)
222 len += 26;
223 else
224 len += nca->payload;
225
226 cmd = skb_put_zero(skb, len);
227 memcpy(&cmd->mfr_id, nca->data, nca->payload);
228 ncsi_cmd_build_header(&cmd->cmd.common, nca);
229
230 return 0;
231}
232
214static struct ncsi_cmd_handler { 233static struct ncsi_cmd_handler {
215 unsigned char type; 234 unsigned char type;
216 int payload; 235 int payload;
@@ -244,7 +263,7 @@ static struct ncsi_cmd_handler {
244 { NCSI_PKT_CMD_GNS, 0, ncsi_cmd_handler_default }, 263 { NCSI_PKT_CMD_GNS, 0, ncsi_cmd_handler_default },
245 { NCSI_PKT_CMD_GNPTS, 0, ncsi_cmd_handler_default }, 264 { NCSI_PKT_CMD_GNPTS, 0, ncsi_cmd_handler_default },
246 { NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default }, 265 { NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default },
247 { NCSI_PKT_CMD_OEM, 0, NULL }, 266 { NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem },
248 { NCSI_PKT_CMD_PLDM, 0, NULL }, 267 { NCSI_PKT_CMD_PLDM, 0, NULL },
249 { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default } 268 { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }
250}; 269};
@@ -316,8 +335,13 @@ int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
316 return -ENOENT; 335 return -ENOENT;
317 } 336 }
318 337
319 /* Get packet payload length and allocate the request */ 338 /* Get packet payload length and allocate the request
320 nca->payload = nch->payload; 339 * It is expected that if length set as negative in
340 * handler structure means caller is initializing it
341 * and setting length in nca before calling xmit function
342 */
343 if (nch->payload >= 0)
344 nca->payload = nch->payload;
321 nr = ncsi_alloc_command(nca); 345 nr = ncsi_alloc_command(nca);
322 if (!nr) 346 if (!nr)
323 return -ENOMEM; 347 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 {
151 unsigned char pad[22]; 151 unsigned char pad[22];
152}; 152};
153 153
154/* OEM Request Command as per NCSI Specification */
155struct ncsi_cmd_oem_pkt {
156 struct ncsi_cmd_pkt_hdr cmd; /* Command header */
157 __be32 mfr_id; /* Manufacture ID */
158 unsigned char data[]; /* OEM Payload Data */
159};
160
161/* OEM Response Packet as per NCSI Specification */
162struct ncsi_rsp_oem_pkt {
163 struct ncsi_rsp_pkt_hdr rsp; /* Command header */
164 __be32 mfr_id; /* Manufacture ID */
165 unsigned char data[]; /* Payload data */
166};
167
154/* Get Link Status */ 168/* Get Link Status */
155struct ncsi_rsp_gls_pkt { 169struct ncsi_rsp_gls_pkt {
156 struct ncsi_rsp_pkt_hdr rsp; /* Response header */ 170 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)
596 return 0; 596 return 0;
597} 597}
598 598
599static struct ncsi_rsp_oem_handler {
600 unsigned int mfr_id;
601 int (*handler)(struct ncsi_request *nr);
602} ncsi_rsp_oem_handlers[] = {
603 { NCSI_OEM_MFR_MLX_ID, NULL },
604 { NCSI_OEM_MFR_BCM_ID, NULL }
605};
606
607/* Response handler for OEM command */
608static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
609{
610 struct ncsi_rsp_oem_pkt *rsp;
611 struct ncsi_rsp_oem_handler *nrh = NULL;
612 unsigned int mfr_id, i;
613
614 /* Get the response header */
615 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
616 mfr_id = ntohl(rsp->mfr_id);
617
618 /* Check for manufacturer id and Find the handler */
619 for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
620 if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
621 if (ncsi_rsp_oem_handlers[i].handler)
622 nrh = &ncsi_rsp_oem_handlers[i];
623 else
624 nrh = NULL;
625
626 break;
627 }
628 }
629
630 if (!nrh) {
631 netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
632 mfr_id);
633 return -ENOENT;
634 }
635
636 /* Process the packet */
637 return nrh->handler(nr);
638}
639
599static int ncsi_rsp_handler_gvi(struct ncsi_request *nr) 640static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
600{ 641{
601 struct ncsi_rsp_gvi_pkt *rsp; 642 struct ncsi_rsp_gvi_pkt *rsp;
@@ -932,7 +973,7 @@ static struct ncsi_rsp_handler {
932 { NCSI_PKT_RSP_GNS, 172, ncsi_rsp_handler_gns }, 973 { NCSI_PKT_RSP_GNS, 172, ncsi_rsp_handler_gns },
933 { NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts }, 974 { NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts },
934 { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps }, 975 { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
935 { NCSI_PKT_RSP_OEM, 0, NULL }, 976 { NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
936 { NCSI_PKT_RSP_PLDM, 0, NULL }, 977 { NCSI_PKT_RSP_PLDM, 0, NULL },
937 { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid } 978 { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }
938}; 979};