diff options
author | Vijay Khemka <vijaykhemka@fb.com> | 2018-10-05 13:46:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-05 17:54:47 -0400 |
commit | fb4ee67529ff3e4c5874768477887c2df5714c96 (patch) | |
tree | bf3176bd5f28d89058a23f3b88ebdf165bd1dad5 | |
parent | 6f8474922b443fd4a89a5dd5b891a3c6a144b9c7 (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.h | 5 | ||||
-rw-r--r-- | net/ncsi/ncsi-cmd.c | 30 | ||||
-rw-r--r-- | net/ncsi/ncsi-pkt.h | 14 | ||||
-rw-r--r-- | 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 { | |||
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 | |||
71 | struct ncsi_channel_version { | 75 | struct 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 | ||
310 | extern struct list_head ncsi_dev_list; | 315 | 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, | |||
211 | return 0; | 211 | return 0; |
212 | } | 212 | } |
213 | 213 | ||
214 | static 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 | |||
214 | static struct ncsi_cmd_handler { | 233 | static 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 */ | ||
155 | struct 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 */ | ||
162 | struct 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 */ |
155 | struct ncsi_rsp_gls_pkt { | 169 | struct 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 | ||
599 | static 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 */ | ||
608 | static 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 | |||
599 | static int ncsi_rsp_handler_gvi(struct ncsi_request *nr) | 640 | static 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 | }; |