Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/ncsi/ncsi-rsp.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright Gavin Shan, IBM Corporation 2016.
4
*/
5
6
#include <linux/module.h>
7
#include <linux/kernel.h>
8
#include <linux/init.h>
9
#include <linux/netdevice.h>
10
#include <linux/etherdevice.h>
11
#include <linux/skbuff.h>
12
13
#include <net/ncsi.h>
14
#include <net/net_namespace.h>
15
#include <net/sock.h>
16
#include <net/genetlink.h>
17
18
#include "internal.h"
19
#include "ncsi-pkt.h"
20
#include "ncsi-netlink.h"
21
22
/* Nibbles within [0xA, 0xF] add zero "0" to the returned value.
23
* Optional fields (encoded as 0xFF) will default to zero.
24
*/
25
static u8 decode_bcd_u8(u8 x)
26
{
27
int lo = x & 0xF;
28
int hi = x >> 4;
29
30
lo = lo < 0xA ? lo : 0;
31
hi = hi < 0xA ? hi : 0;
32
return lo + hi * 10;
33
}
34
35
static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
36
unsigned short payload)
37
{
38
struct ncsi_rsp_pkt_hdr *h;
39
u32 checksum;
40
__be32 *pchecksum;
41
42
/* Check NCSI packet header. We don't need validate
43
* the packet type, which should have been checked
44
* before calling this function.
45
*/
46
h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);
47
48
if (h->common.revision != NCSI_PKT_REVISION) {
49
netdev_dbg(nr->ndp->ndev.dev,
50
"NCSI: unsupported header revision\n");
51
return -EINVAL;
52
}
53
if (ntohs(h->common.length) != payload) {
54
netdev_dbg(nr->ndp->ndev.dev,
55
"NCSI: payload length mismatched\n");
56
return -EINVAL;
57
}
58
59
/* Check on code and reason */
60
if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED ||
61
ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) {
62
netdev_dbg(nr->ndp->ndev.dev,
63
"NCSI: non zero response/reason code %04xh, %04xh\n",
64
ntohs(h->code), ntohs(h->reason));
65
return -EPERM;
66
}
67
68
/* Validate checksum, which might be zeroes if the
69
* sender doesn't support checksum according to NCSI
70
* specification.
71
*/
72
pchecksum = (__be32 *)((void *)(h + 1) + ALIGN(payload, 4) - 4);
73
if (ntohl(*pchecksum) == 0)
74
return 0;
75
76
checksum = ncsi_calculate_checksum((unsigned char *)h,
77
sizeof(*h) + payload - 4);
78
79
if (*pchecksum != htonl(checksum)) {
80
netdev_dbg(nr->ndp->ndev.dev,
81
"NCSI: checksum mismatched; recd: %08x calc: %08x\n",
82
*pchecksum, htonl(checksum));
83
return -EINVAL;
84
}
85
86
return 0;
87
}
88
89
static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
90
{
91
struct ncsi_rsp_pkt *rsp;
92
struct ncsi_dev_priv *ndp = nr->ndp;
93
struct ncsi_package *np;
94
struct ncsi_channel *nc;
95
unsigned char id;
96
97
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
98
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, &np, &nc);
99
if (!nc) {
100
if (ndp->flags & NCSI_DEV_PROBED)
101
return -ENXIO;
102
103
id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
104
nc = ncsi_add_channel(np, id);
105
}
106
107
return nc ? 0 : -ENODEV;
108
}
109
110
static int ncsi_rsp_handler_sp(struct ncsi_request *nr)
111
{
112
struct ncsi_rsp_pkt *rsp;
113
struct ncsi_dev_priv *ndp = nr->ndp;
114
struct ncsi_package *np;
115
unsigned char id;
116
117
/* Add the package if it's not existing. Otherwise,
118
* to change the state of its child channels.
119
*/
120
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
121
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
122
&np, NULL);
123
if (!np) {
124
if (ndp->flags & NCSI_DEV_PROBED)
125
return -ENXIO;
126
127
id = NCSI_PACKAGE_INDEX(rsp->rsp.common.channel);
128
np = ncsi_add_package(ndp, id);
129
if (!np)
130
return -ENODEV;
131
}
132
133
return 0;
134
}
135
136
static int ncsi_rsp_handler_dp(struct ncsi_request *nr)
137
{
138
struct ncsi_rsp_pkt *rsp;
139
struct ncsi_dev_priv *ndp = nr->ndp;
140
struct ncsi_package *np;
141
struct ncsi_channel *nc;
142
unsigned long flags;
143
144
/* Find the package */
145
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
146
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
147
&np, NULL);
148
if (!np)
149
return -ENODEV;
150
151
/* Change state of all channels attached to the package */
152
NCSI_FOR_EACH_CHANNEL(np, nc) {
153
spin_lock_irqsave(&nc->lock, flags);
154
nc->state = NCSI_CHANNEL_INACTIVE;
155
spin_unlock_irqrestore(&nc->lock, flags);
156
}
157
158
return 0;
159
}
160
161
static int ncsi_rsp_handler_ec(struct ncsi_request *nr)
162
{
163
struct ncsi_rsp_pkt *rsp;
164
struct ncsi_dev_priv *ndp = nr->ndp;
165
struct ncsi_channel *nc;
166
struct ncsi_channel_mode *ncm;
167
168
/* Find the package and channel */
169
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
170
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
171
NULL, &nc);
172
if (!nc)
173
return -ENODEV;
174
175
ncm = &nc->modes[NCSI_MODE_ENABLE];
176
if (ncm->enable)
177
return 0;
178
179
ncm->enable = 1;
180
return 0;
181
}
182
183
static int ncsi_rsp_handler_dc(struct ncsi_request *nr)
184
{
185
struct ncsi_rsp_pkt *rsp;
186
struct ncsi_dev_priv *ndp = nr->ndp;
187
struct ncsi_channel *nc;
188
struct ncsi_channel_mode *ncm;
189
int ret;
190
191
ret = ncsi_validate_rsp_pkt(nr, 4);
192
if (ret)
193
return ret;
194
195
/* Find the package and channel */
196
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
197
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
198
NULL, &nc);
199
if (!nc)
200
return -ENODEV;
201
202
ncm = &nc->modes[NCSI_MODE_ENABLE];
203
if (!ncm->enable)
204
return 0;
205
206
ncm->enable = 0;
207
return 0;
208
}
209
210
static int ncsi_rsp_handler_rc(struct ncsi_request *nr)
211
{
212
struct ncsi_rsp_pkt *rsp;
213
struct ncsi_dev_priv *ndp = nr->ndp;
214
struct ncsi_channel *nc;
215
unsigned long flags;
216
217
/* Find the package and channel */
218
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
219
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
220
NULL, &nc);
221
if (!nc)
222
return -ENODEV;
223
224
/* Update state for the specified channel */
225
spin_lock_irqsave(&nc->lock, flags);
226
nc->state = NCSI_CHANNEL_INACTIVE;
227
spin_unlock_irqrestore(&nc->lock, flags);
228
229
return 0;
230
}
231
232
static int ncsi_rsp_handler_ecnt(struct ncsi_request *nr)
233
{
234
struct ncsi_rsp_pkt *rsp;
235
struct ncsi_dev_priv *ndp = nr->ndp;
236
struct ncsi_channel *nc;
237
struct ncsi_channel_mode *ncm;
238
239
/* Find the package and channel */
240
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
241
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
242
NULL, &nc);
243
if (!nc)
244
return -ENODEV;
245
246
ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
247
if (ncm->enable)
248
return 0;
249
250
ncm->enable = 1;
251
return 0;
252
}
253
254
static int ncsi_rsp_handler_dcnt(struct ncsi_request *nr)
255
{
256
struct ncsi_rsp_pkt *rsp;
257
struct ncsi_dev_priv *ndp = nr->ndp;
258
struct ncsi_channel *nc;
259
struct ncsi_channel_mode *ncm;
260
261
/* Find the package and channel */
262
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
263
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
264
NULL, &nc);
265
if (!nc)
266
return -ENODEV;
267
268
ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
269
if (!ncm->enable)
270
return 0;
271
272
ncm->enable = 0;
273
return 0;
274
}
275
276
static int ncsi_rsp_handler_ae(struct ncsi_request *nr)
277
{
278
struct ncsi_cmd_ae_pkt *cmd;
279
struct ncsi_rsp_pkt *rsp;
280
struct ncsi_dev_priv *ndp = nr->ndp;
281
struct ncsi_channel *nc;
282
struct ncsi_channel_mode *ncm;
283
284
/* Find the package and channel */
285
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
286
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
287
NULL, &nc);
288
if (!nc)
289
return -ENODEV;
290
291
/* Check if the AEN has been enabled */
292
ncm = &nc->modes[NCSI_MODE_AEN];
293
if (ncm->enable)
294
return 0;
295
296
/* Update to AEN configuration */
297
cmd = (struct ncsi_cmd_ae_pkt *)skb_network_header(nr->cmd);
298
ncm->enable = 1;
299
ncm->data[0] = cmd->mc_id;
300
ncm->data[1] = ntohl(cmd->mode);
301
302
return 0;
303
}
304
305
static int ncsi_rsp_handler_sl(struct ncsi_request *nr)
306
{
307
struct ncsi_cmd_sl_pkt *cmd;
308
struct ncsi_rsp_pkt *rsp;
309
struct ncsi_dev_priv *ndp = nr->ndp;
310
struct ncsi_channel *nc;
311
struct ncsi_channel_mode *ncm;
312
313
/* Find the package and channel */
314
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
315
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
316
NULL, &nc);
317
if (!nc)
318
return -ENODEV;
319
320
cmd = (struct ncsi_cmd_sl_pkt *)skb_network_header(nr->cmd);
321
ncm = &nc->modes[NCSI_MODE_LINK];
322
ncm->data[0] = ntohl(cmd->mode);
323
ncm->data[1] = ntohl(cmd->oem_mode);
324
325
return 0;
326
}
327
328
static int ncsi_rsp_handler_gls(struct ncsi_request *nr)
329
{
330
struct ncsi_rsp_gls_pkt *rsp;
331
struct ncsi_dev_priv *ndp = nr->ndp;
332
struct ncsi_channel *nc;
333
struct ncsi_channel_mode *ncm;
334
unsigned long flags;
335
336
/* Find the package and channel */
337
rsp = (struct ncsi_rsp_gls_pkt *)skb_network_header(nr->rsp);
338
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
339
NULL, &nc);
340
if (!nc)
341
return -ENODEV;
342
343
ncm = &nc->modes[NCSI_MODE_LINK];
344
ncm->data[2] = ntohl(rsp->status);
345
ncm->data[3] = ntohl(rsp->other);
346
ncm->data[4] = ntohl(rsp->oem_status);
347
348
if (nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN)
349
return 0;
350
351
/* Reset the channel monitor if it has been enabled */
352
spin_lock_irqsave(&nc->lock, flags);
353
nc->monitor.state = NCSI_CHANNEL_MONITOR_START;
354
spin_unlock_irqrestore(&nc->lock, flags);
355
356
return 0;
357
}
358
359
static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
360
{
361
struct ncsi_cmd_svf_pkt *cmd;
362
struct ncsi_rsp_pkt *rsp;
363
struct ncsi_dev_priv *ndp = nr->ndp;
364
struct ncsi_channel *nc;
365
struct ncsi_channel_vlan_filter *ncf;
366
unsigned long flags;
367
void *bitmap;
368
369
/* Find the package and channel */
370
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
371
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
372
NULL, &nc);
373
if (!nc)
374
return -ENODEV;
375
376
cmd = (struct ncsi_cmd_svf_pkt *)skb_network_header(nr->cmd);
377
ncf = &nc->vlan_filter;
378
if (cmd->index == 0 || cmd->index > ncf->n_vids)
379
return -ERANGE;
380
381
/* Add or remove the VLAN filter. Remember HW indexes from 1 */
382
spin_lock_irqsave(&nc->lock, flags);
383
bitmap = &ncf->bitmap;
384
if (!(cmd->enable & 0x1)) {
385
if (test_and_clear_bit(cmd->index - 1, bitmap))
386
ncf->vids[cmd->index - 1] = 0;
387
} else {
388
set_bit(cmd->index - 1, bitmap);
389
ncf->vids[cmd->index - 1] = ntohs(cmd->vlan);
390
}
391
spin_unlock_irqrestore(&nc->lock, flags);
392
393
return 0;
394
}
395
396
static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
397
{
398
struct ncsi_cmd_ev_pkt *cmd;
399
struct ncsi_rsp_pkt *rsp;
400
struct ncsi_dev_priv *ndp = nr->ndp;
401
struct ncsi_channel *nc;
402
struct ncsi_channel_mode *ncm;
403
404
/* Find the package and channel */
405
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
406
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
407
NULL, &nc);
408
if (!nc)
409
return -ENODEV;
410
411
/* Check if VLAN mode has been enabled */
412
ncm = &nc->modes[NCSI_MODE_VLAN];
413
if (ncm->enable)
414
return 0;
415
416
/* Update to VLAN mode */
417
cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
418
ncm->enable = 1;
419
ncm->data[0] = ntohl((__force __be32)cmd->mode);
420
421
return 0;
422
}
423
424
static int ncsi_rsp_handler_dv(struct ncsi_request *nr)
425
{
426
struct ncsi_rsp_pkt *rsp;
427
struct ncsi_dev_priv *ndp = nr->ndp;
428
struct ncsi_channel *nc;
429
struct ncsi_channel_mode *ncm;
430
431
/* Find the package and channel */
432
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
433
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
434
NULL, &nc);
435
if (!nc)
436
return -ENODEV;
437
438
/* Check if VLAN mode has been enabled */
439
ncm = &nc->modes[NCSI_MODE_VLAN];
440
if (!ncm->enable)
441
return 0;
442
443
/* Update to VLAN mode */
444
ncm->enable = 0;
445
return 0;
446
}
447
448
static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
449
{
450
struct ncsi_cmd_sma_pkt *cmd;
451
struct ncsi_rsp_pkt *rsp;
452
struct ncsi_dev_priv *ndp = nr->ndp;
453
struct ncsi_channel *nc;
454
struct ncsi_channel_mac_filter *ncf;
455
unsigned long flags;
456
void *bitmap;
457
bool enabled;
458
int index;
459
460
461
/* Find the package and channel */
462
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
463
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
464
NULL, &nc);
465
if (!nc)
466
return -ENODEV;
467
468
/* According to NCSI spec 1.01, the mixed filter table
469
* isn't supported yet.
470
*/
471
cmd = (struct ncsi_cmd_sma_pkt *)skb_network_header(nr->cmd);
472
enabled = cmd->at_e & 0x1;
473
ncf = &nc->mac_filter;
474
bitmap = &ncf->bitmap;
475
476
if (cmd->index == 0 ||
477
cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
478
return -ERANGE;
479
480
index = (cmd->index - 1) * ETH_ALEN;
481
spin_lock_irqsave(&nc->lock, flags);
482
if (enabled) {
483
set_bit(cmd->index - 1, bitmap);
484
memcpy(&ncf->addrs[index], cmd->mac, ETH_ALEN);
485
} else {
486
clear_bit(cmd->index - 1, bitmap);
487
eth_zero_addr(&ncf->addrs[index]);
488
}
489
spin_unlock_irqrestore(&nc->lock, flags);
490
491
return 0;
492
}
493
494
static int ncsi_rsp_handler_ebf(struct ncsi_request *nr)
495
{
496
struct ncsi_cmd_ebf_pkt *cmd;
497
struct ncsi_rsp_pkt *rsp;
498
struct ncsi_dev_priv *ndp = nr->ndp;
499
struct ncsi_channel *nc;
500
struct ncsi_channel_mode *ncm;
501
502
/* Find the package and channel */
503
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
504
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, NULL, &nc);
505
if (!nc)
506
return -ENODEV;
507
508
/* Check if broadcast filter has been enabled */
509
ncm = &nc->modes[NCSI_MODE_BC];
510
if (ncm->enable)
511
return 0;
512
513
/* Update to broadcast filter mode */
514
cmd = (struct ncsi_cmd_ebf_pkt *)skb_network_header(nr->cmd);
515
ncm->enable = 1;
516
ncm->data[0] = ntohl(cmd->mode);
517
518
return 0;
519
}
520
521
static int ncsi_rsp_handler_dbf(struct ncsi_request *nr)
522
{
523
struct ncsi_rsp_pkt *rsp;
524
struct ncsi_dev_priv *ndp = nr->ndp;
525
struct ncsi_channel *nc;
526
struct ncsi_channel_mode *ncm;
527
528
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
529
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
530
NULL, &nc);
531
if (!nc)
532
return -ENODEV;
533
534
/* Check if broadcast filter isn't enabled */
535
ncm = &nc->modes[NCSI_MODE_BC];
536
if (!ncm->enable)
537
return 0;
538
539
/* Update to broadcast filter mode */
540
ncm->enable = 0;
541
ncm->data[0] = 0;
542
543
return 0;
544
}
545
546
static int ncsi_rsp_handler_egmf(struct ncsi_request *nr)
547
{
548
struct ncsi_cmd_egmf_pkt *cmd;
549
struct ncsi_rsp_pkt *rsp;
550
struct ncsi_dev_priv *ndp = nr->ndp;
551
struct ncsi_channel *nc;
552
struct ncsi_channel_mode *ncm;
553
554
/* Find the channel */
555
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
556
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
557
NULL, &nc);
558
if (!nc)
559
return -ENODEV;
560
561
/* Check if multicast filter has been enabled */
562
ncm = &nc->modes[NCSI_MODE_MC];
563
if (ncm->enable)
564
return 0;
565
566
/* Update to multicast filter mode */
567
cmd = (struct ncsi_cmd_egmf_pkt *)skb_network_header(nr->cmd);
568
ncm->enable = 1;
569
ncm->data[0] = ntohl(cmd->mode);
570
571
return 0;
572
}
573
574
static int ncsi_rsp_handler_dgmf(struct ncsi_request *nr)
575
{
576
struct ncsi_rsp_pkt *rsp;
577
struct ncsi_dev_priv *ndp = nr->ndp;
578
struct ncsi_channel *nc;
579
struct ncsi_channel_mode *ncm;
580
581
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
582
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
583
NULL, &nc);
584
if (!nc)
585
return -ENODEV;
586
587
/* Check if multicast filter has been enabled */
588
ncm = &nc->modes[NCSI_MODE_MC];
589
if (!ncm->enable)
590
return 0;
591
592
/* Update to multicast filter mode */
593
ncm->enable = 0;
594
ncm->data[0] = 0;
595
596
return 0;
597
}
598
599
static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
600
{
601
struct ncsi_cmd_snfc_pkt *cmd;
602
struct ncsi_rsp_pkt *rsp;
603
struct ncsi_dev_priv *ndp = nr->ndp;
604
struct ncsi_channel *nc;
605
struct ncsi_channel_mode *ncm;
606
607
/* Find the channel */
608
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
609
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
610
NULL, &nc);
611
if (!nc)
612
return -ENODEV;
613
614
/* Check if flow control has been enabled */
615
ncm = &nc->modes[NCSI_MODE_FC];
616
if (ncm->enable)
617
return 0;
618
619
/* Update to flow control mode */
620
cmd = (struct ncsi_cmd_snfc_pkt *)skb_network_header(nr->cmd);
621
ncm->enable = 1;
622
ncm->data[0] = cmd->mode;
623
624
return 0;
625
}
626
627
/* Response handler for Get Mac Address command */
628
static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id)
629
{
630
struct ncsi_dev_priv *ndp = nr->ndp;
631
struct sockaddr_storage *saddr = &ndp->pending_mac;
632
struct net_device *ndev = ndp->ndev.dev;
633
struct ncsi_rsp_oem_pkt *rsp;
634
u32 mac_addr_off = 0;
635
636
/* Get the response header */
637
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
638
639
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
640
if (mfr_id == NCSI_OEM_MFR_BCM_ID)
641
mac_addr_off = BCM_MAC_ADDR_OFFSET;
642
else if (mfr_id == NCSI_OEM_MFR_MLX_ID)
643
mac_addr_off = MLX_MAC_ADDR_OFFSET;
644
else if (mfr_id == NCSI_OEM_MFR_INTEL_ID)
645
mac_addr_off = INTEL_MAC_ADDR_OFFSET;
646
647
saddr->ss_family = ndev->type;
648
memcpy(saddr->__data, &rsp->data[mac_addr_off], ETH_ALEN);
649
if (mfr_id == NCSI_OEM_MFR_BCM_ID || mfr_id == NCSI_OEM_MFR_INTEL_ID)
650
eth_addr_inc(saddr->__data);
651
if (!is_valid_ether_addr(saddr->__data))
652
return -ENXIO;
653
654
/* Set the flag for GMA command which should only be called once */
655
ndp->gma_flag = 1;
656
657
return 0;
658
}
659
660
/* Response handler for Mellanox card */
661
static int ncsi_rsp_handler_oem_mlx(struct ncsi_request *nr)
662
{
663
struct ncsi_rsp_oem_mlx_pkt *mlx;
664
struct ncsi_rsp_oem_pkt *rsp;
665
666
/* Get the response header */
667
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
668
mlx = (struct ncsi_rsp_oem_mlx_pkt *)(rsp->data);
669
670
if (mlx->cmd == NCSI_OEM_MLX_CMD_GMA &&
671
mlx->param == NCSI_OEM_MLX_CMD_GMA_PARAM)
672
return ncsi_rsp_handler_oem_gma(nr, NCSI_OEM_MFR_MLX_ID);
673
return 0;
674
}
675
676
/* Response handler for Broadcom card */
677
static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
678
{
679
struct ncsi_rsp_oem_bcm_pkt *bcm;
680
struct ncsi_rsp_oem_pkt *rsp;
681
682
/* Get the response header */
683
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
684
bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
685
686
if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
687
return ncsi_rsp_handler_oem_gma(nr, NCSI_OEM_MFR_BCM_ID);
688
return 0;
689
}
690
691
/* Response handler for Intel card */
692
static int ncsi_rsp_handler_oem_intel(struct ncsi_request *nr)
693
{
694
struct ncsi_rsp_oem_intel_pkt *intel;
695
struct ncsi_rsp_oem_pkt *rsp;
696
697
/* Get the response header */
698
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
699
intel = (struct ncsi_rsp_oem_intel_pkt *)(rsp->data);
700
701
if (intel->cmd == NCSI_OEM_INTEL_CMD_GMA)
702
return ncsi_rsp_handler_oem_gma(nr, NCSI_OEM_MFR_INTEL_ID);
703
704
return 0;
705
}
706
707
static struct ncsi_rsp_oem_handler {
708
unsigned int mfr_id;
709
int (*handler)(struct ncsi_request *nr);
710
} ncsi_rsp_oem_handlers[] = {
711
{ NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
712
{ NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm },
713
{ NCSI_OEM_MFR_INTEL_ID, ncsi_rsp_handler_oem_intel }
714
};
715
716
/* Response handler for OEM command */
717
static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
718
{
719
struct ncsi_rsp_oem_handler *nrh = NULL;
720
struct ncsi_rsp_oem_pkt *rsp;
721
unsigned int mfr_id, i;
722
723
/* Get the response header */
724
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
725
mfr_id = ntohl(rsp->mfr_id);
726
727
/* Check for manufacturer id and Find the handler */
728
for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
729
if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
730
if (ncsi_rsp_oem_handlers[i].handler)
731
nrh = &ncsi_rsp_oem_handlers[i];
732
else
733
nrh = NULL;
734
735
break;
736
}
737
}
738
739
if (!nrh) {
740
netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
741
mfr_id);
742
return -ENOENT;
743
}
744
745
/* Process the packet */
746
return nrh->handler(nr);
747
}
748
749
static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
750
{
751
struct ncsi_rsp_gvi_pkt *rsp;
752
struct ncsi_dev_priv *ndp = nr->ndp;
753
struct ncsi_channel *nc;
754
struct ncsi_channel_version *ncv;
755
int i;
756
757
/* Find the channel */
758
rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
759
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
760
NULL, &nc);
761
if (!nc)
762
return -ENODEV;
763
764
/* Update channel's version info
765
*
766
* Major, minor, and update fields are supposed to be
767
* unsigned integers encoded as packed BCD.
768
*
769
* Alpha1 and alpha2 are ISO/IEC 8859-1 characters.
770
*/
771
ncv = &nc->version;
772
ncv->major = decode_bcd_u8(rsp->major);
773
ncv->minor = decode_bcd_u8(rsp->minor);
774
ncv->update = decode_bcd_u8(rsp->update);
775
ncv->alpha1 = rsp->alpha1;
776
ncv->alpha2 = rsp->alpha2;
777
memcpy(ncv->fw_name, rsp->fw_name, 12);
778
ncv->fw_name[12] = '\0';
779
ncv->fw_version = ntohl(rsp->fw_version);
780
for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
781
ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
782
ncv->mf_id = ntohl(rsp->mf_id);
783
784
return 0;
785
}
786
787
static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
788
{
789
struct ncsi_rsp_gc_pkt *rsp;
790
struct ncsi_dev_priv *ndp = nr->ndp;
791
struct ncsi_channel *nc;
792
struct ncsi_package *np;
793
size_t size;
794
795
/* Find the channel */
796
rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
797
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
798
&np, &nc);
799
if (!nc)
800
return -ENODEV;
801
802
/* Update channel's capabilities */
803
nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
804
NCSI_CAP_GENERIC_MASK;
805
nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
806
NCSI_CAP_BC_MASK;
807
nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
808
NCSI_CAP_MC_MASK;
809
nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
810
nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
811
NCSI_CAP_AEN_MASK;
812
nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
813
NCSI_CAP_VLAN_MASK;
814
815
size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
816
nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
817
if (!nc->mac_filter.addrs)
818
return -ENOMEM;
819
nc->mac_filter.n_uc = rsp->uc_cnt;
820
nc->mac_filter.n_mc = rsp->mc_cnt;
821
nc->mac_filter.n_mixed = rsp->mixed_cnt;
822
823
nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
824
sizeof(*nc->vlan_filter.vids),
825
GFP_ATOMIC);
826
if (!nc->vlan_filter.vids)
827
return -ENOMEM;
828
/* Set VLAN filters active so they are cleared in the first
829
* configuration state
830
*/
831
nc->vlan_filter.bitmap = U64_MAX;
832
nc->vlan_filter.n_vids = rsp->vlan_cnt;
833
np->ndp->channel_count = rsp->channel_cnt;
834
835
return 0;
836
}
837
838
static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
839
{
840
struct ncsi_channel_vlan_filter *ncvf;
841
struct ncsi_channel_mac_filter *ncmf;
842
struct ncsi_dev_priv *ndp = nr->ndp;
843
struct ncsi_rsp_gp_pkt *rsp;
844
struct ncsi_channel *nc;
845
unsigned short enable;
846
unsigned char *pdata;
847
unsigned long flags;
848
void *bitmap;
849
int i;
850
851
/* Find the channel */
852
rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
853
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
854
NULL, &nc);
855
if (!nc)
856
return -ENODEV;
857
858
/* Modes with explicit enabled indications */
859
if (ntohl(rsp->valid_modes) & 0x1) { /* BC filter mode */
860
nc->modes[NCSI_MODE_BC].enable = 1;
861
nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
862
}
863
if (ntohl(rsp->valid_modes) & 0x2) /* Channel enabled */
864
nc->modes[NCSI_MODE_ENABLE].enable = 1;
865
if (ntohl(rsp->valid_modes) & 0x4) /* Channel Tx enabled */
866
nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
867
if (ntohl(rsp->valid_modes) & 0x8) /* MC filter mode */
868
nc->modes[NCSI_MODE_MC].enable = 1;
869
870
/* Modes without explicit enabled indications */
871
nc->modes[NCSI_MODE_LINK].enable = 1;
872
nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
873
nc->modes[NCSI_MODE_VLAN].enable = 1;
874
nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
875
nc->modes[NCSI_MODE_FC].enable = 1;
876
nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
877
nc->modes[NCSI_MODE_AEN].enable = 1;
878
nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
879
880
/* MAC addresses filter table */
881
pdata = (unsigned char *)rsp + 48;
882
enable = rsp->mac_enable;
883
ncmf = &nc->mac_filter;
884
spin_lock_irqsave(&nc->lock, flags);
885
bitmap = &ncmf->bitmap;
886
for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
887
if (!(enable & (0x1 << i)))
888
clear_bit(i, bitmap);
889
else
890
set_bit(i, bitmap);
891
892
memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
893
}
894
spin_unlock_irqrestore(&nc->lock, flags);
895
896
/* VLAN filter table */
897
enable = ntohs(rsp->vlan_enable);
898
ncvf = &nc->vlan_filter;
899
bitmap = &ncvf->bitmap;
900
spin_lock_irqsave(&nc->lock, flags);
901
for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
902
if (!(enable & (0x1 << i)))
903
clear_bit(i, bitmap);
904
else
905
set_bit(i, bitmap);
906
907
ncvf->vids[i] = ntohs(*(__be16 *)pdata);
908
}
909
spin_unlock_irqrestore(&nc->lock, flags);
910
911
return 0;
912
}
913
914
static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
915
{
916
struct ncsi_rsp_gcps_pkt *rsp;
917
struct ncsi_dev_priv *ndp = nr->ndp;
918
struct ncsi_channel *nc;
919
struct ncsi_channel_stats *ncs;
920
921
/* Find the channel */
922
rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
923
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
924
NULL, &nc);
925
if (!nc)
926
return -ENODEV;
927
928
/* Update HNC's statistics */
929
ncs = &nc->stats;
930
ncs->hnc_cnt = be64_to_cpu(rsp->cnt);
931
ncs->hnc_rx_bytes = be64_to_cpu(rsp->rx_bytes);
932
ncs->hnc_tx_bytes = be64_to_cpu(rsp->tx_bytes);
933
ncs->hnc_rx_uc_pkts = be64_to_cpu(rsp->rx_uc_pkts);
934
ncs->hnc_rx_mc_pkts = be64_to_cpu(rsp->rx_mc_pkts);
935
ncs->hnc_rx_bc_pkts = be64_to_cpu(rsp->rx_bc_pkts);
936
ncs->hnc_tx_uc_pkts = be64_to_cpu(rsp->tx_uc_pkts);
937
ncs->hnc_tx_mc_pkts = be64_to_cpu(rsp->tx_mc_pkts);
938
ncs->hnc_tx_bc_pkts = be64_to_cpu(rsp->tx_bc_pkts);
939
ncs->hnc_fcs_err = ntohl(rsp->fcs_err);
940
ncs->hnc_align_err = ntohl(rsp->align_err);
941
ncs->hnc_false_carrier = ntohl(rsp->false_carrier);
942
ncs->hnc_runt_pkts = ntohl(rsp->runt_pkts);
943
ncs->hnc_jabber_pkts = ntohl(rsp->jabber_pkts);
944
ncs->hnc_rx_pause_xon = ntohl(rsp->rx_pause_xon);
945
ncs->hnc_rx_pause_xoff = ntohl(rsp->rx_pause_xoff);
946
ncs->hnc_tx_pause_xon = ntohl(rsp->tx_pause_xon);
947
ncs->hnc_tx_pause_xoff = ntohl(rsp->tx_pause_xoff);
948
ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
949
ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
950
ncs->hnc_l_collision = ntohl(rsp->l_collision);
951
ncs->hnc_e_collision = ntohl(rsp->e_collision);
952
ncs->hnc_rx_ctl_frames = ntohl(rsp->rx_ctl_frames);
953
ncs->hnc_rx_64_frames = ntohl(rsp->rx_64_frames);
954
ncs->hnc_rx_127_frames = ntohl(rsp->rx_127_frames);
955
ncs->hnc_rx_255_frames = ntohl(rsp->rx_255_frames);
956
ncs->hnc_rx_511_frames = ntohl(rsp->rx_511_frames);
957
ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
958
ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
959
ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
960
ncs->hnc_tx_64_frames = ntohl(rsp->tx_64_frames);
961
ncs->hnc_tx_127_frames = ntohl(rsp->tx_127_frames);
962
ncs->hnc_tx_255_frames = ntohl(rsp->tx_255_frames);
963
ncs->hnc_tx_511_frames = ntohl(rsp->tx_511_frames);
964
ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
965
ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
966
ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
967
ncs->hnc_rx_valid_bytes = be64_to_cpu(rsp->rx_valid_bytes);
968
ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts);
969
ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
970
971
return 0;
972
}
973
974
static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
975
{
976
struct ncsi_rsp_gns_pkt *rsp;
977
struct ncsi_dev_priv *ndp = nr->ndp;
978
struct ncsi_channel *nc;
979
struct ncsi_channel_stats *ncs;
980
981
/* Find the channel */
982
rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
983
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
984
NULL, &nc);
985
if (!nc)
986
return -ENODEV;
987
988
/* Update HNC's statistics */
989
ncs = &nc->stats;
990
ncs->ncsi_rx_cmds = ntohl(rsp->rx_cmds);
991
ncs->ncsi_dropped_cmds = ntohl(rsp->dropped_cmds);
992
ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
993
ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
994
ncs->ncsi_rx_pkts = ntohl(rsp->rx_pkts);
995
ncs->ncsi_tx_pkts = ntohl(rsp->tx_pkts);
996
ncs->ncsi_tx_aen_pkts = ntohl(rsp->tx_aen_pkts);
997
998
return 0;
999
}
1000
1001
static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
1002
{
1003
struct ncsi_rsp_gnpts_pkt *rsp;
1004
struct ncsi_dev_priv *ndp = nr->ndp;
1005
struct ncsi_channel *nc;
1006
struct ncsi_channel_stats *ncs;
1007
1008
/* Find the channel */
1009
rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
1010
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1011
NULL, &nc);
1012
if (!nc)
1013
return -ENODEV;
1014
1015
/* Update HNC's statistics */
1016
ncs = &nc->stats;
1017
ncs->pt_tx_pkts = ntohl(rsp->tx_pkts);
1018
ncs->pt_tx_dropped = ntohl(rsp->tx_dropped);
1019
ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
1020
ncs->pt_tx_us_err = ntohl(rsp->tx_us_err);
1021
ncs->pt_rx_pkts = ntohl(rsp->rx_pkts);
1022
ncs->pt_rx_dropped = ntohl(rsp->rx_dropped);
1023
ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
1024
ncs->pt_rx_us_err = ntohl(rsp->rx_us_err);
1025
ncs->pt_rx_os_err = ntohl(rsp->rx_os_err);
1026
1027
return 0;
1028
}
1029
1030
static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
1031
{
1032
struct ncsi_rsp_gps_pkt *rsp;
1033
struct ncsi_dev_priv *ndp = nr->ndp;
1034
struct ncsi_package *np;
1035
1036
/* Find the package */
1037
rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
1038
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1039
&np, NULL);
1040
if (!np)
1041
return -ENODEV;
1042
1043
return 0;
1044
}
1045
1046
static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
1047
{
1048
struct ncsi_rsp_gpuuid_pkt *rsp;
1049
struct ncsi_dev_priv *ndp = nr->ndp;
1050
struct ncsi_package *np;
1051
1052
/* Find the package */
1053
rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
1054
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1055
&np, NULL);
1056
if (!np)
1057
return -ENODEV;
1058
1059
memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
1060
1061
return 0;
1062
}
1063
1064
static int ncsi_rsp_handler_pldm(struct ncsi_request *nr)
1065
{
1066
return 0;
1067
}
1068
1069
static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
1070
{
1071
struct ncsi_dev_priv *ndp = nr->ndp;
1072
struct ncsi_rsp_pkt *rsp;
1073
struct ncsi_package *np;
1074
struct ncsi_channel *nc;
1075
int ret;
1076
1077
/* Find the package */
1078
rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
1079
ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1080
&np, &nc);
1081
if (!np)
1082
return -ENODEV;
1083
1084
ret = ncsi_send_netlink_rsp(nr, np, nc);
1085
1086
return ret;
1087
}
1088
1089
static int ncsi_rsp_handler_gmcma(struct ncsi_request *nr)
1090
{
1091
struct ncsi_dev_priv *ndp = nr->ndp;
1092
struct sockaddr_storage *saddr = &ndp->pending_mac;
1093
struct net_device *ndev = ndp->ndev.dev;
1094
struct ncsi_rsp_gmcma_pkt *rsp;
1095
int i;
1096
1097
rsp = (struct ncsi_rsp_gmcma_pkt *)skb_network_header(nr->rsp);
1098
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
1099
1100
netdev_info(ndev, "NCSI: Received %d provisioned MAC addresses\n",
1101
rsp->address_count);
1102
for (i = 0; i < rsp->address_count; i++) {
1103
netdev_info(ndev, "NCSI: MAC address %d: %02x:%02x:%02x:%02x:%02x:%02x\n",
1104
i, rsp->addresses[i][0], rsp->addresses[i][1],
1105
rsp->addresses[i][2], rsp->addresses[i][3],
1106
rsp->addresses[i][4], rsp->addresses[i][5]);
1107
}
1108
1109
saddr->ss_family = ndev->type;
1110
for (i = 0; i < rsp->address_count; i++) {
1111
if (!is_valid_ether_addr(rsp->addresses[i])) {
1112
netdev_warn(ndev, "NCSI: Unable to assign %pM to device\n",
1113
rsp->addresses[i]);
1114
continue;
1115
}
1116
memcpy(saddr->__data, rsp->addresses[i], ETH_ALEN);
1117
netdev_warn(ndev, "NCSI: Will set MAC address to %pM\n", saddr->__data);
1118
break;
1119
}
1120
1121
ndp->gma_flag = 1;
1122
return 0;
1123
}
1124
1125
static struct ncsi_rsp_handler {
1126
unsigned char type;
1127
int payload;
1128
int (*handler)(struct ncsi_request *nr);
1129
} ncsi_rsp_handlers[] = {
1130
{ NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis },
1131
{ NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp },
1132
{ NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp },
1133
{ NCSI_PKT_RSP_EC, 4, ncsi_rsp_handler_ec },
1134
{ NCSI_PKT_RSP_DC, 4, ncsi_rsp_handler_dc },
1135
{ NCSI_PKT_RSP_RC, 4, ncsi_rsp_handler_rc },
1136
{ NCSI_PKT_RSP_ECNT, 4, ncsi_rsp_handler_ecnt },
1137
{ NCSI_PKT_RSP_DCNT, 4, ncsi_rsp_handler_dcnt },
1138
{ NCSI_PKT_RSP_AE, 4, ncsi_rsp_handler_ae },
1139
{ NCSI_PKT_RSP_SL, 4, ncsi_rsp_handler_sl },
1140
{ NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
1141
{ NCSI_PKT_RSP_SVF, 4, ncsi_rsp_handler_svf },
1142
{ NCSI_PKT_RSP_EV, 4, ncsi_rsp_handler_ev },
1143
{ NCSI_PKT_RSP_DV, 4, ncsi_rsp_handler_dv },
1144
{ NCSI_PKT_RSP_SMA, 4, ncsi_rsp_handler_sma },
1145
{ NCSI_PKT_RSP_EBF, 4, ncsi_rsp_handler_ebf },
1146
{ NCSI_PKT_RSP_DBF, 4, ncsi_rsp_handler_dbf },
1147
{ NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf },
1148
{ NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf },
1149
{ NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc },
1150
{ NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi },
1151
{ NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
1152
{ NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp },
1153
{ NCSI_PKT_RSP_GCPS, 204, ncsi_rsp_handler_gcps },
1154
{ NCSI_PKT_RSP_GNS, 32, ncsi_rsp_handler_gns },
1155
{ NCSI_PKT_RSP_GNPTS, 48, ncsi_rsp_handler_gnpts },
1156
{ NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
1157
{ NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
1158
{ NCSI_PKT_RSP_PLDM, -1, ncsi_rsp_handler_pldm },
1159
{ NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid },
1160
{ NCSI_PKT_RSP_QPNPR, -1, ncsi_rsp_handler_pldm },
1161
{ NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm },
1162
{ NCSI_PKT_RSP_GMCMA, -1, ncsi_rsp_handler_gmcma },
1163
};
1164
1165
int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
1166
struct packet_type *pt, struct net_device *orig_dev)
1167
{
1168
struct ncsi_rsp_handler *nrh = NULL;
1169
struct ncsi_dev *nd;
1170
struct ncsi_dev_priv *ndp;
1171
struct ncsi_request *nr;
1172
struct ncsi_pkt_hdr *hdr;
1173
unsigned long flags;
1174
int payload, i, ret;
1175
1176
/* Find the NCSI device */
1177
nd = ncsi_find_dev(orig_dev);
1178
ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
1179
if (!ndp)
1180
return -ENODEV;
1181
1182
/* Check if it is AEN packet */
1183
hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
1184
if (hdr->type == NCSI_PKT_AEN)
1185
return ncsi_aen_handler(ndp, skb);
1186
1187
/* Find the handler */
1188
for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
1189
if (ncsi_rsp_handlers[i].type == hdr->type) {
1190
if (ncsi_rsp_handlers[i].handler)
1191
nrh = &ncsi_rsp_handlers[i];
1192
else
1193
nrh = NULL;
1194
1195
break;
1196
}
1197
}
1198
1199
if (!nrh) {
1200
netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
1201
hdr->type);
1202
return -ENOENT;
1203
}
1204
1205
/* Associate with the request */
1206
spin_lock_irqsave(&ndp->lock, flags);
1207
nr = &ndp->requests[hdr->id];
1208
if (!nr->used) {
1209
spin_unlock_irqrestore(&ndp->lock, flags);
1210
return -ENODEV;
1211
}
1212
1213
nr->rsp = skb;
1214
if (!nr->enabled) {
1215
spin_unlock_irqrestore(&ndp->lock, flags);
1216
ret = -ENOENT;
1217
goto out;
1218
}
1219
1220
/* Validate the packet */
1221
spin_unlock_irqrestore(&ndp->lock, flags);
1222
payload = nrh->payload;
1223
if (payload < 0)
1224
payload = ntohs(hdr->length);
1225
ret = ncsi_validate_rsp_pkt(nr, payload);
1226
if (ret) {
1227
netdev_warn(ndp->ndev.dev,
1228
"NCSI: 'bad' packet ignored for type 0x%x\n",
1229
hdr->type);
1230
1231
if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1232
if (ret == -EPERM)
1233
goto out_netlink;
1234
else
1235
ncsi_send_netlink_err(ndp->ndev.dev,
1236
nr->snd_seq,
1237
nr->snd_portid,
1238
&nr->nlhdr,
1239
ret);
1240
}
1241
goto out;
1242
}
1243
1244
/* Process the packet */
1245
ret = nrh->handler(nr);
1246
if (ret)
1247
netdev_err(ndp->ndev.dev,
1248
"NCSI: Handler for packet type 0x%x returned %d\n",
1249
hdr->type, ret);
1250
1251
out_netlink:
1252
if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1253
ret = ncsi_rsp_handler_netlink(nr);
1254
if (ret) {
1255
netdev_err(ndp->ndev.dev,
1256
"NCSI: Netlink handler for packet type 0x%x returned %d\n",
1257
hdr->type, ret);
1258
}
1259
}
1260
1261
out:
1262
ncsi_free_request(nr);
1263
return ret;
1264
}
1265
1266