diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-07-18 21:54:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-19 23:49:16 -0400 |
commit | 6389eaa7fa9c3ee6c7d39f6087b86660d17236ac (patch) | |
tree | 5c915baea8427248f016c7c4630852ee37e3f538 | |
parent | 2d283bdd079c0ad4da020bbc9e9c2a4280823098 (diff) |
net/ncsi: NCSI command packet handler
The NCSI command packets are sent from MC (Management Controller)
to remote end. They are used for multiple purposes: probe existing
NCSI package/channel, retrieve NCSI channel's capability, configure
NCSI channel etc.
This defines struct to represent NCSI command packets and introduces
function ncsi_xmit_cmd(), which will be used to transmit NCSI command
packet according to the request. The request is represented by struct
ncsi_cmd_arg.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Acked-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/uapi/linux/if_ether.h | 1 | ||||
-rw-r--r-- | net/ncsi/Makefile | 2 | ||||
-rw-r--r-- | net/ncsi/internal.h | 19 | ||||
-rw-r--r-- | net/ncsi/ncsi-cmd.c | 367 | ||||
-rw-r--r-- | net/ncsi/ncsi-pkt.h | 171 |
5 files changed, 559 insertions, 1 deletions
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index cec849a239f6..117d02e0fc31 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h | |||
@@ -87,6 +87,7 @@ | |||
87 | #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ | 87 | #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ |
88 | #define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */ | 88 | #define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */ |
89 | #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ | 89 | #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ |
90 | #define ETH_P_NCSI 0x88F8 /* NCSI protocol */ | ||
90 | #define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */ | 91 | #define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */ |
91 | #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ | 92 | #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ |
92 | #define ETH_P_TDLS 0x890D /* TDLS */ | 93 | #define ETH_P_TDLS 0x890D /* TDLS */ |
diff --git a/net/ncsi/Makefile b/net/ncsi/Makefile index 07b5625155d7..abc404631ca8 100644 --- a/net/ncsi/Makefile +++ b/net/ncsi/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # | 1 | # |
2 | # Makefile for NCSI API | 2 | # Makefile for NCSI API |
3 | # | 3 | # |
4 | obj-$(CONFIG_NET_NCSI) += ncsi-manage.o | 4 | obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-manage.o |
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index 89028e1f83cd..3d81697a97d0 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h | |||
@@ -220,6 +220,21 @@ struct ncsi_dev_priv { | |||
220 | struct list_head node; /* Form NCSI device list */ | 220 | struct list_head node; /* Form NCSI device list */ |
221 | }; | 221 | }; |
222 | 222 | ||
223 | struct ncsi_cmd_arg { | ||
224 | struct ncsi_dev_priv *ndp; /* Associated NCSI device */ | ||
225 | unsigned char type; /* Command in the NCSI packet */ | ||
226 | unsigned char id; /* Request ID (sequence number) */ | ||
227 | unsigned char package; /* Destination package ID */ | ||
228 | unsigned char channel; /* Detination channel ID or 0x1f */ | ||
229 | unsigned short payload; /* Command packet payload length */ | ||
230 | bool driven; /* Drive the state machine? */ | ||
231 | union { | ||
232 | unsigned char bytes[16]; /* Command packet specific data */ | ||
233 | unsigned short words[8]; | ||
234 | unsigned int dwords[4]; | ||
235 | }; | ||
236 | }; | ||
237 | |||
223 | extern struct list_head ncsi_dev_list; | 238 | extern struct list_head ncsi_dev_list; |
224 | extern spinlock_t ncsi_dev_lock; | 239 | extern spinlock_t ncsi_dev_lock; |
225 | 240 | ||
@@ -253,4 +268,8 @@ struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, bool driven); | |||
253 | void ncsi_free_request(struct ncsi_request *nr); | 268 | void ncsi_free_request(struct ncsi_request *nr); |
254 | struct ncsi_dev *ncsi_find_dev(struct net_device *dev); | 269 | struct ncsi_dev *ncsi_find_dev(struct net_device *dev); |
255 | 270 | ||
271 | /* Packet handlers */ | ||
272 | u32 ncsi_calculate_checksum(unsigned char *data, int len); | ||
273 | int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca); | ||
274 | |||
256 | #endif /* __NCSI_INTERNAL_H__ */ | 275 | #endif /* __NCSI_INTERNAL_H__ */ |
diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c new file mode 100644 index 000000000000..21057a8ceeac --- /dev/null +++ b/net/ncsi/ncsi-cmd.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * Copyright Gavin Shan, IBM Corporation 2016. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/etherdevice.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <linux/skbuff.h> | ||
16 | |||
17 | #include <net/ncsi.h> | ||
18 | #include <net/net_namespace.h> | ||
19 | #include <net/sock.h> | ||
20 | |||
21 | #include "internal.h" | ||
22 | #include "ncsi-pkt.h" | ||
23 | |||
24 | u32 ncsi_calculate_checksum(unsigned char *data, int len) | ||
25 | { | ||
26 | u32 checksum = 0; | ||
27 | int i; | ||
28 | |||
29 | for (i = 0; i < len; i += 2) | ||
30 | checksum += (((u32)data[i] << 8) | data[i + 1]); | ||
31 | |||
32 | checksum = (~checksum + 1); | ||
33 | return checksum; | ||
34 | } | ||
35 | |||
36 | /* This function should be called after the data area has been | ||
37 | * populated completely. | ||
38 | */ | ||
39 | static void ncsi_cmd_build_header(struct ncsi_pkt_hdr *h, | ||
40 | struct ncsi_cmd_arg *nca) | ||
41 | { | ||
42 | u32 checksum; | ||
43 | __be32 *pchecksum; | ||
44 | |||
45 | h->mc_id = 0; | ||
46 | h->revision = NCSI_PKT_REVISION; | ||
47 | h->reserved = 0; | ||
48 | h->id = nca->id; | ||
49 | h->type = nca->type; | ||
50 | h->channel = NCSI_TO_CHANNEL(nca->package, | ||
51 | nca->channel); | ||
52 | h->length = htons(nca->payload); | ||
53 | h->reserved1[0] = 0; | ||
54 | h->reserved1[1] = 0; | ||
55 | |||
56 | /* Fill with calculated checksum */ | ||
57 | checksum = ncsi_calculate_checksum((unsigned char *)h, | ||
58 | sizeof(*h) + nca->payload); | ||
59 | pchecksum = (__be32 *)((void *)h + sizeof(struct ncsi_pkt_hdr) + | ||
60 | nca->payload); | ||
61 | *pchecksum = htonl(checksum); | ||
62 | } | ||
63 | |||
64 | static int ncsi_cmd_handler_default(struct sk_buff *skb, | ||
65 | struct ncsi_cmd_arg *nca) | ||
66 | { | ||
67 | struct ncsi_cmd_pkt *cmd; | ||
68 | |||
69 | cmd = (struct ncsi_cmd_pkt *)skb_put(skb, sizeof(*cmd)); | ||
70 | memset(cmd, 0, sizeof(*cmd)); | ||
71 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int ncsi_cmd_handler_sp(struct sk_buff *skb, | ||
77 | struct ncsi_cmd_arg *nca) | ||
78 | { | ||
79 | struct ncsi_cmd_sp_pkt *cmd; | ||
80 | |||
81 | cmd = (struct ncsi_cmd_sp_pkt *)skb_put(skb, sizeof(*cmd)); | ||
82 | memset(cmd, 0, sizeof(*cmd)); | ||
83 | cmd->hw_arbitration = nca->bytes[0]; | ||
84 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int ncsi_cmd_handler_dc(struct sk_buff *skb, | ||
90 | struct ncsi_cmd_arg *nca) | ||
91 | { | ||
92 | struct ncsi_cmd_dc_pkt *cmd; | ||
93 | |||
94 | cmd = (struct ncsi_cmd_dc_pkt *)skb_put(skb, sizeof(*cmd)); | ||
95 | memset(cmd, 0, sizeof(*cmd)); | ||
96 | cmd->ald = nca->bytes[0]; | ||
97 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int ncsi_cmd_handler_rc(struct sk_buff *skb, | ||
103 | struct ncsi_cmd_arg *nca) | ||
104 | { | ||
105 | struct ncsi_cmd_rc_pkt *cmd; | ||
106 | |||
107 | cmd = (struct ncsi_cmd_rc_pkt *)skb_put(skb, sizeof(*cmd)); | ||
108 | memset(cmd, 0, sizeof(*cmd)); | ||
109 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int ncsi_cmd_handler_ae(struct sk_buff *skb, | ||
115 | struct ncsi_cmd_arg *nca) | ||
116 | { | ||
117 | struct ncsi_cmd_ae_pkt *cmd; | ||
118 | |||
119 | cmd = (struct ncsi_cmd_ae_pkt *)skb_put(skb, sizeof(*cmd)); | ||
120 | memset(cmd, 0, sizeof(*cmd)); | ||
121 | cmd->mc_id = nca->bytes[0]; | ||
122 | cmd->mode = htonl(nca->dwords[1]); | ||
123 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int ncsi_cmd_handler_sl(struct sk_buff *skb, | ||
129 | struct ncsi_cmd_arg *nca) | ||
130 | { | ||
131 | struct ncsi_cmd_sl_pkt *cmd; | ||
132 | |||
133 | cmd = (struct ncsi_cmd_sl_pkt *)skb_put(skb, sizeof(*cmd)); | ||
134 | memset(cmd, 0, sizeof(*cmd)); | ||
135 | cmd->mode = htonl(nca->dwords[0]); | ||
136 | cmd->oem_mode = htonl(nca->dwords[1]); | ||
137 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int ncsi_cmd_handler_svf(struct sk_buff *skb, | ||
143 | struct ncsi_cmd_arg *nca) | ||
144 | { | ||
145 | struct ncsi_cmd_svf_pkt *cmd; | ||
146 | |||
147 | cmd = (struct ncsi_cmd_svf_pkt *)skb_put(skb, sizeof(*cmd)); | ||
148 | memset(cmd, 0, sizeof(*cmd)); | ||
149 | cmd->vlan = htons(nca->words[0]); | ||
150 | cmd->index = nca->bytes[2]; | ||
151 | cmd->enable = nca->bytes[3]; | ||
152 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static int ncsi_cmd_handler_ev(struct sk_buff *skb, | ||
158 | struct ncsi_cmd_arg *nca) | ||
159 | { | ||
160 | struct ncsi_cmd_ev_pkt *cmd; | ||
161 | |||
162 | cmd = (struct ncsi_cmd_ev_pkt *)skb_put(skb, sizeof(*cmd)); | ||
163 | memset(cmd, 0, sizeof(*cmd)); | ||
164 | cmd->mode = nca->bytes[0]; | ||
165 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int ncsi_cmd_handler_sma(struct sk_buff *skb, | ||
171 | struct ncsi_cmd_arg *nca) | ||
172 | { | ||
173 | struct ncsi_cmd_sma_pkt *cmd; | ||
174 | int i; | ||
175 | |||
176 | cmd = (struct ncsi_cmd_sma_pkt *)skb_put(skb, sizeof(*cmd)); | ||
177 | memset(cmd, 0, sizeof(*cmd)); | ||
178 | for (i = 0; i < 6; i++) | ||
179 | cmd->mac[i] = nca->bytes[i]; | ||
180 | cmd->index = nca->bytes[6]; | ||
181 | cmd->at_e = nca->bytes[7]; | ||
182 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int ncsi_cmd_handler_ebf(struct sk_buff *skb, | ||
188 | struct ncsi_cmd_arg *nca) | ||
189 | { | ||
190 | struct ncsi_cmd_ebf_pkt *cmd; | ||
191 | |||
192 | cmd = (struct ncsi_cmd_ebf_pkt *)skb_put(skb, sizeof(*cmd)); | ||
193 | memset(cmd, 0, sizeof(*cmd)); | ||
194 | cmd->mode = htonl(nca->dwords[0]); | ||
195 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int ncsi_cmd_handler_egmf(struct sk_buff *skb, | ||
201 | struct ncsi_cmd_arg *nca) | ||
202 | { | ||
203 | struct ncsi_cmd_egmf_pkt *cmd; | ||
204 | |||
205 | cmd = (struct ncsi_cmd_egmf_pkt *)skb_put(skb, sizeof(*cmd)); | ||
206 | memset(cmd, 0, sizeof(*cmd)); | ||
207 | cmd->mode = htonl(nca->dwords[0]); | ||
208 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static int ncsi_cmd_handler_snfc(struct sk_buff *skb, | ||
214 | struct ncsi_cmd_arg *nca) | ||
215 | { | ||
216 | struct ncsi_cmd_snfc_pkt *cmd; | ||
217 | |||
218 | cmd = (struct ncsi_cmd_snfc_pkt *)skb_put(skb, sizeof(*cmd)); | ||
219 | memset(cmd, 0, sizeof(*cmd)); | ||
220 | cmd->mode = nca->bytes[0]; | ||
221 | ncsi_cmd_build_header(&cmd->cmd.common, nca); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static struct ncsi_cmd_handler { | ||
227 | unsigned char type; | ||
228 | int payload; | ||
229 | int (*handler)(struct sk_buff *skb, | ||
230 | struct ncsi_cmd_arg *nca); | ||
231 | } ncsi_cmd_handlers[] = { | ||
232 | { NCSI_PKT_CMD_CIS, 0, ncsi_cmd_handler_default }, | ||
233 | { NCSI_PKT_CMD_SP, 4, ncsi_cmd_handler_sp }, | ||
234 | { NCSI_PKT_CMD_DP, 0, ncsi_cmd_handler_default }, | ||
235 | { NCSI_PKT_CMD_EC, 0, ncsi_cmd_handler_default }, | ||
236 | { NCSI_PKT_CMD_DC, 4, ncsi_cmd_handler_dc }, | ||
237 | { NCSI_PKT_CMD_RC, 4, ncsi_cmd_handler_rc }, | ||
238 | { NCSI_PKT_CMD_ECNT, 0, ncsi_cmd_handler_default }, | ||
239 | { NCSI_PKT_CMD_DCNT, 0, ncsi_cmd_handler_default }, | ||
240 | { NCSI_PKT_CMD_AE, 8, ncsi_cmd_handler_ae }, | ||
241 | { NCSI_PKT_CMD_SL, 8, ncsi_cmd_handler_sl }, | ||
242 | { NCSI_PKT_CMD_GLS, 0, ncsi_cmd_handler_default }, | ||
243 | { NCSI_PKT_CMD_SVF, 4, ncsi_cmd_handler_svf }, | ||
244 | { NCSI_PKT_CMD_EV, 4, ncsi_cmd_handler_ev }, | ||
245 | { NCSI_PKT_CMD_DV, 0, ncsi_cmd_handler_default }, | ||
246 | { NCSI_PKT_CMD_SMA, 8, ncsi_cmd_handler_sma }, | ||
247 | { NCSI_PKT_CMD_EBF, 4, ncsi_cmd_handler_ebf }, | ||
248 | { NCSI_PKT_CMD_DBF, 0, ncsi_cmd_handler_default }, | ||
249 | { NCSI_PKT_CMD_EGMF, 4, ncsi_cmd_handler_egmf }, | ||
250 | { NCSI_PKT_CMD_DGMF, 0, ncsi_cmd_handler_default }, | ||
251 | { NCSI_PKT_CMD_SNFC, 4, ncsi_cmd_handler_snfc }, | ||
252 | { NCSI_PKT_CMD_GVI, 0, ncsi_cmd_handler_default }, | ||
253 | { NCSI_PKT_CMD_GC, 0, ncsi_cmd_handler_default }, | ||
254 | { NCSI_PKT_CMD_GP, 0, ncsi_cmd_handler_default }, | ||
255 | { NCSI_PKT_CMD_GCPS, 0, ncsi_cmd_handler_default }, | ||
256 | { NCSI_PKT_CMD_GNS, 0, ncsi_cmd_handler_default }, | ||
257 | { NCSI_PKT_CMD_GNPTS, 0, ncsi_cmd_handler_default }, | ||
258 | { NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default }, | ||
259 | { NCSI_PKT_CMD_OEM, 0, NULL }, | ||
260 | { NCSI_PKT_CMD_PLDM, 0, NULL }, | ||
261 | { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default } | ||
262 | }; | ||
263 | |||
264 | static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca) | ||
265 | { | ||
266 | struct ncsi_dev_priv *ndp = nca->ndp; | ||
267 | struct ncsi_dev *nd = &ndp->ndev; | ||
268 | struct net_device *dev = nd->dev; | ||
269 | int hlen = LL_RESERVED_SPACE(dev); | ||
270 | int tlen = dev->needed_tailroom; | ||
271 | int len = hlen + tlen; | ||
272 | struct sk_buff *skb; | ||
273 | struct ncsi_request *nr; | ||
274 | |||
275 | nr = ncsi_alloc_request(ndp, nca->driven); | ||
276 | if (!nr) | ||
277 | return NULL; | ||
278 | |||
279 | /* NCSI command packet has 16-bytes header, payload, 4 bytes checksum. | ||
280 | * The packet needs padding if its payload is less than 26 bytes to | ||
281 | * meet 64 bytes minimal ethernet frame length. | ||
282 | */ | ||
283 | len += sizeof(struct ncsi_cmd_pkt_hdr) + 4; | ||
284 | if (nca->payload < 26) | ||
285 | len += 26; | ||
286 | else | ||
287 | len += nca->payload; | ||
288 | |||
289 | /* Allocate skb */ | ||
290 | skb = alloc_skb(len, GFP_ATOMIC); | ||
291 | if (!skb) { | ||
292 | ncsi_free_request(nr); | ||
293 | return NULL; | ||
294 | } | ||
295 | |||
296 | nr->cmd = skb; | ||
297 | skb_reserve(skb, hlen); | ||
298 | skb_reset_network_header(skb); | ||
299 | |||
300 | skb->dev = dev; | ||
301 | skb->protocol = htons(ETH_P_NCSI); | ||
302 | |||
303 | return nr; | ||
304 | } | ||
305 | |||
306 | int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca) | ||
307 | { | ||
308 | struct ncsi_request *nr; | ||
309 | struct ethhdr *eh; | ||
310 | struct ncsi_cmd_handler *nch = NULL; | ||
311 | int i, ret; | ||
312 | |||
313 | /* Search for the handler */ | ||
314 | for (i = 0; i < ARRAY_SIZE(ncsi_cmd_handlers); i++) { | ||
315 | if (ncsi_cmd_handlers[i].type == nca->type) { | ||
316 | if (ncsi_cmd_handlers[i].handler) | ||
317 | nch = &ncsi_cmd_handlers[i]; | ||
318 | else | ||
319 | nch = NULL; | ||
320 | |||
321 | break; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | if (!nch) { | ||
326 | netdev_err(nca->ndp->ndev.dev, | ||
327 | "Cannot send packet with type 0x%02x\n", nca->type); | ||
328 | return -ENOENT; | ||
329 | } | ||
330 | |||
331 | /* Get packet payload length and allocate the request */ | ||
332 | nca->payload = nch->payload; | ||
333 | nr = ncsi_alloc_command(nca); | ||
334 | if (!nr) | ||
335 | return -ENOMEM; | ||
336 | |||
337 | /* Prepare the packet */ | ||
338 | nca->id = nr->id; | ||
339 | ret = nch->handler(nr->cmd, nca); | ||
340 | if (ret) { | ||
341 | ncsi_free_request(nr); | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | /* Fill the ethernet header */ | ||
346 | eh = (struct ethhdr *)skb_push(nr->cmd, sizeof(*eh)); | ||
347 | eh->h_proto = htons(ETH_P_NCSI); | ||
348 | eth_broadcast_addr(eh->h_dest); | ||
349 | eth_broadcast_addr(eh->h_source); | ||
350 | |||
351 | /* Start the timer for the request that might not have | ||
352 | * corresponding response. Given NCSI is an internal | ||
353 | * connection a 1 second delay should be sufficient. | ||
354 | */ | ||
355 | nr->enabled = true; | ||
356 | mod_timer(&nr->timer, jiffies + 1 * HZ); | ||
357 | |||
358 | /* Send NCSI packet */ | ||
359 | skb_get(nr->cmd); | ||
360 | ret = dev_queue_xmit(nr->cmd); | ||
361 | if (ret < 0) { | ||
362 | ncsi_free_request(nr); | ||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | return 0; | ||
367 | } | ||
diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h new file mode 100644 index 000000000000..548145863c49 --- /dev/null +++ b/net/ncsi/ncsi-pkt.h | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Copyright Gavin Shan, IBM Corporation 2016. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef __NCSI_PKT_H__ | ||
11 | #define __NCSI_PKT_H__ | ||
12 | |||
13 | struct ncsi_pkt_hdr { | ||
14 | unsigned char mc_id; /* Management controller ID */ | ||
15 | unsigned char revision; /* NCSI version - 0x01 */ | ||
16 | unsigned char reserved; /* Reserved */ | ||
17 | unsigned char id; /* Packet sequence number */ | ||
18 | unsigned char type; /* Packet type */ | ||
19 | unsigned char channel; /* Network controller ID */ | ||
20 | __be16 length; /* Payload length */ | ||
21 | __be32 reserved1[2]; /* Reserved */ | ||
22 | }; | ||
23 | |||
24 | struct ncsi_cmd_pkt_hdr { | ||
25 | struct ncsi_pkt_hdr common; /* Common NCSI packet header */ | ||
26 | }; | ||
27 | |||
28 | /* NCSI common command packet */ | ||
29 | struct ncsi_cmd_pkt { | ||
30 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
31 | __be32 checksum; /* Checksum */ | ||
32 | unsigned char pad[26]; | ||
33 | }; | ||
34 | |||
35 | /* Select Package */ | ||
36 | struct ncsi_cmd_sp_pkt { | ||
37 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
38 | unsigned char reserved[3]; /* Reserved */ | ||
39 | unsigned char hw_arbitration; /* HW arbitration */ | ||
40 | __be32 checksum; /* Checksum */ | ||
41 | unsigned char pad[22]; | ||
42 | }; | ||
43 | |||
44 | /* Disable Channel */ | ||
45 | struct ncsi_cmd_dc_pkt { | ||
46 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
47 | unsigned char reserved[3]; /* Reserved */ | ||
48 | unsigned char ald; /* Allow link down */ | ||
49 | __be32 checksum; /* Checksum */ | ||
50 | unsigned char pad[22]; | ||
51 | }; | ||
52 | |||
53 | /* Reset Channel */ | ||
54 | struct ncsi_cmd_rc_pkt { | ||
55 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
56 | __be32 reserved; /* Reserved */ | ||
57 | __be32 checksum; /* Checksum */ | ||
58 | unsigned char pad[22]; | ||
59 | }; | ||
60 | |||
61 | /* AEN Enable */ | ||
62 | struct ncsi_cmd_ae_pkt { | ||
63 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
64 | unsigned char reserved[3]; /* Reserved */ | ||
65 | unsigned char mc_id; /* MC ID */ | ||
66 | __be32 mode; /* AEN working mode */ | ||
67 | __be32 checksum; /* Checksum */ | ||
68 | unsigned char pad[18]; | ||
69 | }; | ||
70 | |||
71 | /* Set Link */ | ||
72 | struct ncsi_cmd_sl_pkt { | ||
73 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
74 | __be32 mode; /* Link working mode */ | ||
75 | __be32 oem_mode; /* OEM link mode */ | ||
76 | __be32 checksum; /* Checksum */ | ||
77 | unsigned char pad[18]; | ||
78 | }; | ||
79 | |||
80 | /* Set VLAN Filter */ | ||
81 | struct ncsi_cmd_svf_pkt { | ||
82 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
83 | __be16 reserved; /* Reserved */ | ||
84 | __be16 vlan; /* VLAN ID */ | ||
85 | __be16 reserved1; /* Reserved */ | ||
86 | unsigned char index; /* VLAN table index */ | ||
87 | unsigned char enable; /* Enable or disable */ | ||
88 | __be32 checksum; /* Checksum */ | ||
89 | unsigned char pad[14]; | ||
90 | }; | ||
91 | |||
92 | /* Enable VLAN */ | ||
93 | struct ncsi_cmd_ev_pkt { | ||
94 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
95 | unsigned char reserved[3]; /* Reserved */ | ||
96 | unsigned char mode; /* VLAN filter mode */ | ||
97 | __be32 checksum; /* Checksum */ | ||
98 | unsigned char pad[22]; | ||
99 | }; | ||
100 | |||
101 | /* Set MAC Address */ | ||
102 | struct ncsi_cmd_sma_pkt { | ||
103 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
104 | unsigned char mac[6]; /* MAC address */ | ||
105 | unsigned char index; /* MAC table index */ | ||
106 | unsigned char at_e; /* Addr type and operation */ | ||
107 | __be32 checksum; /* Checksum */ | ||
108 | unsigned char pad[18]; | ||
109 | }; | ||
110 | |||
111 | /* Enable Broadcast Filter */ | ||
112 | struct ncsi_cmd_ebf_pkt { | ||
113 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
114 | __be32 mode; /* Filter mode */ | ||
115 | __be32 checksum; /* Checksum */ | ||
116 | unsigned char pad[22]; | ||
117 | }; | ||
118 | |||
119 | /* Enable Global Multicast Filter */ | ||
120 | struct ncsi_cmd_egmf_pkt { | ||
121 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
122 | __be32 mode; /* Global MC mode */ | ||
123 | __be32 checksum; /* Checksum */ | ||
124 | unsigned char pad[22]; | ||
125 | }; | ||
126 | |||
127 | /* Set NCSI Flow Control */ | ||
128 | struct ncsi_cmd_snfc_pkt { | ||
129 | struct ncsi_cmd_pkt_hdr cmd; /* Command header */ | ||
130 | unsigned char reserved[3]; /* Reserved */ | ||
131 | unsigned char mode; /* Flow control mode */ | ||
132 | __be32 checksum; /* Checksum */ | ||
133 | unsigned char pad[22]; | ||
134 | }; | ||
135 | |||
136 | /* NCSI packet revision */ | ||
137 | #define NCSI_PKT_REVISION 0x01 | ||
138 | |||
139 | /* NCSI packet commands */ | ||
140 | #define NCSI_PKT_CMD_CIS 0x00 /* Clear Initial State */ | ||
141 | #define NCSI_PKT_CMD_SP 0x01 /* Select Package */ | ||
142 | #define NCSI_PKT_CMD_DP 0x02 /* Deselect Package */ | ||
143 | #define NCSI_PKT_CMD_EC 0x03 /* Enable Channel */ | ||
144 | #define NCSI_PKT_CMD_DC 0x04 /* Disable Channel */ | ||
145 | #define NCSI_PKT_CMD_RC 0x05 /* Reset Channel */ | ||
146 | #define NCSI_PKT_CMD_ECNT 0x06 /* Enable Channel Network Tx */ | ||
147 | #define NCSI_PKT_CMD_DCNT 0x07 /* Disable Channel Network Tx */ | ||
148 | #define NCSI_PKT_CMD_AE 0x08 /* AEN Enable */ | ||
149 | #define NCSI_PKT_CMD_SL 0x09 /* Set Link */ | ||
150 | #define NCSI_PKT_CMD_GLS 0x0a /* Get Link */ | ||
151 | #define NCSI_PKT_CMD_SVF 0x0b /* Set VLAN Filter */ | ||
152 | #define NCSI_PKT_CMD_EV 0x0c /* Enable VLAN */ | ||
153 | #define NCSI_PKT_CMD_DV 0x0d /* Disable VLAN */ | ||
154 | #define NCSI_PKT_CMD_SMA 0x0e /* Set MAC address */ | ||
155 | #define NCSI_PKT_CMD_EBF 0x10 /* Enable Broadcast Filter */ | ||
156 | #define NCSI_PKT_CMD_DBF 0x11 /* Disable Broadcast Filter */ | ||
157 | #define NCSI_PKT_CMD_EGMF 0x12 /* Enable Global Multicast Filter */ | ||
158 | #define NCSI_PKT_CMD_DGMF 0x13 /* Disable Global Multicast Filter */ | ||
159 | #define NCSI_PKT_CMD_SNFC 0x14 /* Set NCSI Flow Control */ | ||
160 | #define NCSI_PKT_CMD_GVI 0x15 /* Get Version ID */ | ||
161 | #define NCSI_PKT_CMD_GC 0x16 /* Get Capabilities */ | ||
162 | #define NCSI_PKT_CMD_GP 0x17 /* Get Parameters */ | ||
163 | #define NCSI_PKT_CMD_GCPS 0x18 /* Get Controller Packet Statistics */ | ||
164 | #define NCSI_PKT_CMD_GNS 0x19 /* Get NCSI Statistics */ | ||
165 | #define NCSI_PKT_CMD_GNPTS 0x1a /* Get NCSI Pass-throu Statistics */ | ||
166 | #define NCSI_PKT_CMD_GPS 0x1b /* Get package status */ | ||
167 | #define NCSI_PKT_CMD_OEM 0x50 /* OEM */ | ||
168 | #define NCSI_PKT_CMD_PLDM 0x51 /* PLDM request over NCSI over RBT */ | ||
169 | #define NCSI_PKT_CMD_GPUUID 0x52 /* Get package UUID */ | ||
170 | |||
171 | #endif /* __NCSI_PKT_H__ */ | ||