2 * Copyright Gavin Shan, IBM Corporation 2016.
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.
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/netdevice.h>
14 #include <linux/skbuff.h>
17 #include <net/net_namespace.h>
23 static int ncsi_validate_rsp_pkt(struct ncsi_request
*nr
,
24 unsigned short payload
)
26 struct ncsi_rsp_pkt_hdr
*h
;
30 /* Check NCSI packet header. We don't need validate
31 * the packet type, which should have been checked
32 * before calling this function.
34 h
= (struct ncsi_rsp_pkt_hdr
*)skb_network_header(nr
->rsp
);
35 if (h
->common
.revision
!= NCSI_PKT_REVISION
)
37 if (ntohs(h
->common
.length
) != payload
)
40 /* Check on code and reason */
41 if (ntohs(h
->code
) != NCSI_PKT_RSP_C_COMPLETED
||
42 ntohs(h
->reason
) != NCSI_PKT_RSP_R_NO_ERROR
)
45 /* Validate checksum, which might be zeroes if the
46 * sender doesn't support checksum according to NCSI
49 pchecksum
= (__be32
*)((void *)(h
+ 1) + payload
- 4);
50 if (ntohl(*pchecksum
) == 0)
53 checksum
= ncsi_calculate_checksum((unsigned char *)h
,
54 sizeof(*h
) + payload
- 4);
55 if (*pchecksum
!= htonl(checksum
))
61 static int ncsi_rsp_handler_cis(struct ncsi_request
*nr
)
63 struct ncsi_rsp_pkt
*rsp
;
64 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
65 struct ncsi_package
*np
;
66 struct ncsi_channel
*nc
;
69 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
70 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
, &np
, &nc
);
72 id
= NCSI_CHANNEL_INDEX(rsp
->rsp
.common
.channel
);
73 nc
= ncsi_add_channel(np
, id
);
76 return nc
? 0 : -ENODEV
;
79 static int ncsi_rsp_handler_sp(struct ncsi_request
*nr
)
81 struct ncsi_rsp_pkt
*rsp
;
82 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
83 struct ncsi_package
*np
;
86 /* Add the package if it's not existing. Otherwise,
87 * to change the state of its child channels.
89 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
90 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
93 id
= NCSI_PACKAGE_INDEX(rsp
->rsp
.common
.channel
);
94 np
= ncsi_add_package(ndp
, id
);
102 static int ncsi_rsp_handler_dp(struct ncsi_request
*nr
)
104 struct ncsi_rsp_pkt
*rsp
;
105 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
106 struct ncsi_package
*np
;
107 struct ncsi_channel
*nc
;
110 /* Find the package */
111 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
112 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
117 /* Change state of all channels attached to the package */
118 NCSI_FOR_EACH_CHANNEL(np
, nc
) {
119 spin_lock_irqsave(&nc
->lock
, flags
);
120 nc
->state
= NCSI_CHANNEL_INACTIVE
;
121 spin_unlock_irqrestore(&nc
->lock
, flags
);
127 static int ncsi_rsp_handler_ec(struct ncsi_request
*nr
)
129 struct ncsi_rsp_pkt
*rsp
;
130 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
131 struct ncsi_channel
*nc
;
132 struct ncsi_channel_mode
*ncm
;
134 /* Find the package and channel */
135 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
136 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
141 ncm
= &nc
->modes
[NCSI_MODE_ENABLE
];
149 static int ncsi_rsp_handler_dc(struct ncsi_request
*nr
)
151 struct ncsi_rsp_pkt
*rsp
;
152 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
153 struct ncsi_channel
*nc
;
154 struct ncsi_channel_mode
*ncm
;
157 ret
= ncsi_validate_rsp_pkt(nr
, 4);
161 /* Find the package and channel */
162 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
163 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
168 ncm
= &nc
->modes
[NCSI_MODE_ENABLE
];
176 static int ncsi_rsp_handler_rc(struct ncsi_request
*nr
)
178 struct ncsi_rsp_pkt
*rsp
;
179 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
180 struct ncsi_channel
*nc
;
183 /* Find the package and channel */
184 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
185 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
190 /* Update state for the specified channel */
191 spin_lock_irqsave(&nc
->lock
, flags
);
192 nc
->state
= NCSI_CHANNEL_INACTIVE
;
193 spin_unlock_irqrestore(&nc
->lock
, flags
);
198 static int ncsi_rsp_handler_ecnt(struct ncsi_request
*nr
)
200 struct ncsi_rsp_pkt
*rsp
;
201 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
202 struct ncsi_channel
*nc
;
203 struct ncsi_channel_mode
*ncm
;
205 /* Find the package and channel */
206 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
207 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
212 ncm
= &nc
->modes
[NCSI_MODE_TX_ENABLE
];
220 static int ncsi_rsp_handler_dcnt(struct ncsi_request
*nr
)
222 struct ncsi_rsp_pkt
*rsp
;
223 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
224 struct ncsi_channel
*nc
;
225 struct ncsi_channel_mode
*ncm
;
227 /* Find the package and channel */
228 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
229 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
234 ncm
= &nc
->modes
[NCSI_MODE_TX_ENABLE
];
242 static int ncsi_rsp_handler_ae(struct ncsi_request
*nr
)
244 struct ncsi_cmd_ae_pkt
*cmd
;
245 struct ncsi_rsp_pkt
*rsp
;
246 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
247 struct ncsi_channel
*nc
;
248 struct ncsi_channel_mode
*ncm
;
250 /* Find the package and channel */
251 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
252 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
257 /* Check if the AEN has been enabled */
258 ncm
= &nc
->modes
[NCSI_MODE_AEN
];
262 /* Update to AEN configuration */
263 cmd
= (struct ncsi_cmd_ae_pkt
*)skb_network_header(nr
->cmd
);
265 ncm
->data
[0] = cmd
->mc_id
;
266 ncm
->data
[1] = ntohl(cmd
->mode
);
271 static int ncsi_rsp_handler_sl(struct ncsi_request
*nr
)
273 struct ncsi_cmd_sl_pkt
*cmd
;
274 struct ncsi_rsp_pkt
*rsp
;
275 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
276 struct ncsi_channel
*nc
;
277 struct ncsi_channel_mode
*ncm
;
279 /* Find the package and channel */
280 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
281 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
286 cmd
= (struct ncsi_cmd_sl_pkt
*)skb_network_header(nr
->cmd
);
287 ncm
= &nc
->modes
[NCSI_MODE_LINK
];
288 ncm
->data
[0] = ntohl(cmd
->mode
);
289 ncm
->data
[1] = ntohl(cmd
->oem_mode
);
294 static int ncsi_rsp_handler_gls(struct ncsi_request
*nr
)
296 struct ncsi_rsp_gls_pkt
*rsp
;
297 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
298 struct ncsi_channel
*nc
;
299 struct ncsi_channel_mode
*ncm
;
301 /* Find the package and channel */
302 rsp
= (struct ncsi_rsp_gls_pkt
*)skb_network_header(nr
->rsp
);
303 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
308 ncm
= &nc
->modes
[NCSI_MODE_LINK
];
309 ncm
->data
[2] = ntohl(rsp
->status
);
310 ncm
->data
[3] = ntohl(rsp
->other
);
311 ncm
->data
[4] = ntohl(rsp
->oem_status
);
316 static int ncsi_rsp_handler_svf(struct ncsi_request
*nr
)
318 struct ncsi_cmd_svf_pkt
*cmd
;
319 struct ncsi_rsp_pkt
*rsp
;
320 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
321 struct ncsi_channel
*nc
;
322 struct ncsi_channel_filter
*ncf
;
326 /* Find the package and channel */
327 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
328 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
333 cmd
= (struct ncsi_cmd_svf_pkt
*)skb_network_header(nr
->cmd
);
334 ncf
= nc
->filters
[NCSI_FILTER_VLAN
];
337 if (cmd
->index
>= ncf
->total
)
340 /* Add or remove the VLAN filter */
341 if (!(cmd
->enable
& 0x1)) {
342 ret
= ncsi_remove_filter(nc
, NCSI_FILTER_VLAN
, cmd
->index
);
344 vlan
= ntohs(cmd
->vlan
);
345 ret
= ncsi_add_filter(nc
, NCSI_FILTER_VLAN
, &vlan
);
351 static int ncsi_rsp_handler_ev(struct ncsi_request
*nr
)
353 struct ncsi_cmd_ev_pkt
*cmd
;
354 struct ncsi_rsp_pkt
*rsp
;
355 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
356 struct ncsi_channel
*nc
;
357 struct ncsi_channel_mode
*ncm
;
359 /* Find the package and channel */
360 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
361 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
366 /* Check if VLAN mode has been enabled */
367 ncm
= &nc
->modes
[NCSI_MODE_VLAN
];
371 /* Update to VLAN mode */
372 cmd
= (struct ncsi_cmd_ev_pkt
*)skb_network_header(nr
->cmd
);
374 ncm
->data
[0] = ntohl(cmd
->mode
);
379 static int ncsi_rsp_handler_dv(struct ncsi_request
*nr
)
381 struct ncsi_rsp_pkt
*rsp
;
382 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
383 struct ncsi_channel
*nc
;
384 struct ncsi_channel_mode
*ncm
;
386 /* Find the package and channel */
387 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
388 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
393 /* Check if VLAN mode has been enabled */
394 ncm
= &nc
->modes
[NCSI_MODE_VLAN
];
398 /* Update to VLAN mode */
403 static int ncsi_rsp_handler_sma(struct ncsi_request
*nr
)
405 struct ncsi_cmd_sma_pkt
*cmd
;
406 struct ncsi_rsp_pkt
*rsp
;
407 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
408 struct ncsi_channel
*nc
;
409 struct ncsi_channel_filter
*ncf
;
412 /* Find the package and channel */
413 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
414 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
419 /* According to NCSI spec 1.01, the mixed filter table
420 * isn't supported yet.
422 cmd
= (struct ncsi_cmd_sma_pkt
*)skb_network_header(nr
->cmd
);
423 switch (cmd
->at_e
>> 5) {
424 case 0x0: /* UC address */
425 ncf
= nc
->filters
[NCSI_FILTER_UC
];
427 case 0x1: /* MC address */
428 ncf
= nc
->filters
[NCSI_FILTER_MC
];
434 /* Sanity check on the filter */
437 else if (cmd
->index
>= ncf
->total
)
440 bitmap
= &ncf
->bitmap
;
441 if (cmd
->at_e
& 0x1) {
442 if (test_and_set_bit(cmd
->index
, bitmap
))
444 memcpy(ncf
->data
+ 6 * cmd
->index
, cmd
->mac
, 6);
446 if (!test_and_clear_bit(cmd
->index
, bitmap
))
449 memset(ncf
->data
+ 6 * cmd
->index
, 0, 6);
455 static int ncsi_rsp_handler_ebf(struct ncsi_request
*nr
)
457 struct ncsi_cmd_ebf_pkt
*cmd
;
458 struct ncsi_rsp_pkt
*rsp
;
459 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
460 struct ncsi_channel
*nc
;
461 struct ncsi_channel_mode
*ncm
;
463 /* Find the package and channel */
464 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
465 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
, NULL
, &nc
);
469 /* Check if broadcast filter has been enabled */
470 ncm
= &nc
->modes
[NCSI_MODE_BC
];
474 /* Update to broadcast filter mode */
475 cmd
= (struct ncsi_cmd_ebf_pkt
*)skb_network_header(nr
->cmd
);
477 ncm
->data
[0] = ntohl(cmd
->mode
);
482 static int ncsi_rsp_handler_dbf(struct ncsi_request
*nr
)
484 struct ncsi_rsp_pkt
*rsp
;
485 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
486 struct ncsi_channel
*nc
;
487 struct ncsi_channel_mode
*ncm
;
489 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
490 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
495 /* Check if broadcast filter isn't enabled */
496 ncm
= &nc
->modes
[NCSI_MODE_BC
];
500 /* Update to broadcast filter mode */
507 static int ncsi_rsp_handler_egmf(struct ncsi_request
*nr
)
509 struct ncsi_cmd_egmf_pkt
*cmd
;
510 struct ncsi_rsp_pkt
*rsp
;
511 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
512 struct ncsi_channel
*nc
;
513 struct ncsi_channel_mode
*ncm
;
515 /* Find the channel */
516 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
517 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
522 /* Check if multicast filter has been enabled */
523 ncm
= &nc
->modes
[NCSI_MODE_MC
];
527 /* Update to multicast filter mode */
528 cmd
= (struct ncsi_cmd_egmf_pkt
*)skb_network_header(nr
->cmd
);
530 ncm
->data
[0] = ntohl(cmd
->mode
);
535 static int ncsi_rsp_handler_dgmf(struct ncsi_request
*nr
)
537 struct ncsi_rsp_pkt
*rsp
;
538 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
539 struct ncsi_channel
*nc
;
540 struct ncsi_channel_mode
*ncm
;
542 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
543 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
548 /* Check if multicast filter has been enabled */
549 ncm
= &nc
->modes
[NCSI_MODE_MC
];
553 /* Update to multicast filter mode */
560 static int ncsi_rsp_handler_snfc(struct ncsi_request
*nr
)
562 struct ncsi_cmd_snfc_pkt
*cmd
;
563 struct ncsi_rsp_pkt
*rsp
;
564 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
565 struct ncsi_channel
*nc
;
566 struct ncsi_channel_mode
*ncm
;
568 /* Find the channel */
569 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
570 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
575 /* Check if flow control has been enabled */
576 ncm
= &nc
->modes
[NCSI_MODE_FC
];
580 /* Update to flow control mode */
581 cmd
= (struct ncsi_cmd_snfc_pkt
*)skb_network_header(nr
->cmd
);
583 ncm
->data
[0] = cmd
->mode
;
588 static int ncsi_rsp_handler_gvi(struct ncsi_request
*nr
)
590 struct ncsi_rsp_gvi_pkt
*rsp
;
591 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
592 struct ncsi_channel
*nc
;
593 struct ncsi_channel_version
*ncv
;
596 /* Find the channel */
597 rsp
= (struct ncsi_rsp_gvi_pkt
*)skb_network_header(nr
->rsp
);
598 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
603 /* Update to channel's version info */
605 ncv
->version
= ntohl(rsp
->ncsi_version
);
606 ncv
->alpha2
= rsp
->alpha2
;
607 memcpy(ncv
->fw_name
, rsp
->fw_name
, 12);
608 ncv
->fw_version
= ntohl(rsp
->fw_version
);
609 for (i
= 0; i
< ARRAY_SIZE(ncv
->pci_ids
); i
++)
610 ncv
->pci_ids
[i
] = ntohs(rsp
->pci_ids
[i
]);
611 ncv
->mf_id
= ntohl(rsp
->mf_id
);
616 static int ncsi_rsp_handler_gc(struct ncsi_request
*nr
)
618 struct ncsi_rsp_gc_pkt
*rsp
;
619 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
620 struct ncsi_channel
*nc
;
621 struct ncsi_channel_filter
*ncf
;
622 size_t size
, entry_size
;
625 /* Find the channel */
626 rsp
= (struct ncsi_rsp_gc_pkt
*)skb_network_header(nr
->rsp
);
627 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
632 /* Update channel's capabilities */
633 nc
->caps
[NCSI_CAP_GENERIC
].cap
= ntohl(rsp
->cap
) &
634 NCSI_CAP_GENERIC_MASK
;
635 nc
->caps
[NCSI_CAP_BC
].cap
= ntohl(rsp
->bc_cap
) &
637 nc
->caps
[NCSI_CAP_MC
].cap
= ntohl(rsp
->mc_cap
) &
639 nc
->caps
[NCSI_CAP_BUFFER
].cap
= ntohl(rsp
->buf_cap
);
640 nc
->caps
[NCSI_CAP_AEN
].cap
= ntohl(rsp
->aen_cap
) &
642 nc
->caps
[NCSI_CAP_VLAN
].cap
= rsp
->vlan_mode
&
646 for (i
= 0; i
< NCSI_FILTER_MAX
; i
++) {
648 case NCSI_FILTER_VLAN
:
652 case NCSI_FILTER_MIXED
:
653 cnt
= rsp
->mixed_cnt
;
668 if (!cnt
|| nc
->filters
[i
])
671 size
= sizeof(*ncf
) + cnt
* entry_size
;
672 ncf
= kzalloc(size
, GFP_ATOMIC
);
674 pr_warn("%s: Cannot alloc filter table (%d)\n",
682 nc
->filters
[i
] = ncf
;
688 static int ncsi_rsp_handler_gp(struct ncsi_request
*nr
)
690 struct ncsi_rsp_gp_pkt
*rsp
;
691 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
692 struct ncsi_channel
*nc
;
693 unsigned short enable
, vlan
;
694 unsigned char *pdata
;
697 /* Find the channel */
698 rsp
= (struct ncsi_rsp_gp_pkt
*)skb_network_header(nr
->rsp
);
699 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
704 /* Modes with explicit enabled indications */
705 if (ntohl(rsp
->valid_modes
) & 0x1) { /* BC filter mode */
706 nc
->modes
[NCSI_MODE_BC
].enable
= 1;
707 nc
->modes
[NCSI_MODE_BC
].data
[0] = ntohl(rsp
->bc_mode
);
709 if (ntohl(rsp
->valid_modes
) & 0x2) /* Channel enabled */
710 nc
->modes
[NCSI_MODE_ENABLE
].enable
= 1;
711 if (ntohl(rsp
->valid_modes
) & 0x4) /* Channel Tx enabled */
712 nc
->modes
[NCSI_MODE_TX_ENABLE
].enable
= 1;
713 if (ntohl(rsp
->valid_modes
) & 0x8) /* MC filter mode */
714 nc
->modes
[NCSI_MODE_MC
].enable
= 1;
716 /* Modes without explicit enabled indications */
717 nc
->modes
[NCSI_MODE_LINK
].enable
= 1;
718 nc
->modes
[NCSI_MODE_LINK
].data
[0] = ntohl(rsp
->link_mode
);
719 nc
->modes
[NCSI_MODE_VLAN
].enable
= 1;
720 nc
->modes
[NCSI_MODE_VLAN
].data
[0] = rsp
->vlan_mode
;
721 nc
->modes
[NCSI_MODE_FC
].enable
= 1;
722 nc
->modes
[NCSI_MODE_FC
].data
[0] = rsp
->fc_mode
;
723 nc
->modes
[NCSI_MODE_AEN
].enable
= 1;
724 nc
->modes
[NCSI_MODE_AEN
].data
[0] = ntohl(rsp
->aen_mode
);
726 /* MAC addresses filter table */
727 pdata
= (unsigned char *)rsp
+ 48;
728 enable
= rsp
->mac_enable
;
729 for (i
= 0; i
< rsp
->mac_cnt
; i
++, pdata
+= 6) {
730 if (i
>= (nc
->filters
[NCSI_FILTER_UC
]->total
+
731 nc
->filters
[NCSI_FILTER_MC
]->total
))
732 table
= NCSI_FILTER_MIXED
;
733 else if (i
>= nc
->filters
[NCSI_FILTER_UC
]->total
)
734 table
= NCSI_FILTER_MC
;
736 table
= NCSI_FILTER_UC
;
738 if (!(enable
& (0x1 << i
)))
741 if (ncsi_find_filter(nc
, table
, pdata
) >= 0)
744 ncsi_add_filter(nc
, table
, pdata
);
747 /* VLAN filter table */
748 enable
= ntohs(rsp
->vlan_enable
);
749 for (i
= 0; i
< rsp
->vlan_cnt
; i
++, pdata
+= 2) {
750 if (!(enable
& (0x1 << i
)))
753 vlan
= ntohs(*(__be16
*)pdata
);
754 if (ncsi_find_filter(nc
, NCSI_FILTER_VLAN
, &vlan
) >= 0)
757 ncsi_add_filter(nc
, NCSI_FILTER_VLAN
, &vlan
);
763 static int ncsi_rsp_handler_gcps(struct ncsi_request
*nr
)
765 struct ncsi_rsp_gcps_pkt
*rsp
;
766 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
767 struct ncsi_channel
*nc
;
768 struct ncsi_channel_stats
*ncs
;
770 /* Find the channel */
771 rsp
= (struct ncsi_rsp_gcps_pkt
*)skb_network_header(nr
->rsp
);
772 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
777 /* Update HNC's statistics */
779 ncs
->hnc_cnt_hi
= ntohl(rsp
->cnt_hi
);
780 ncs
->hnc_cnt_lo
= ntohl(rsp
->cnt_lo
);
781 ncs
->hnc_rx_bytes
= ntohl(rsp
->rx_bytes
);
782 ncs
->hnc_tx_bytes
= ntohl(rsp
->tx_bytes
);
783 ncs
->hnc_rx_uc_pkts
= ntohl(rsp
->rx_uc_pkts
);
784 ncs
->hnc_rx_mc_pkts
= ntohl(rsp
->rx_mc_pkts
);
785 ncs
->hnc_rx_bc_pkts
= ntohl(rsp
->rx_bc_pkts
);
786 ncs
->hnc_tx_uc_pkts
= ntohl(rsp
->tx_uc_pkts
);
787 ncs
->hnc_tx_mc_pkts
= ntohl(rsp
->tx_mc_pkts
);
788 ncs
->hnc_tx_bc_pkts
= ntohl(rsp
->tx_bc_pkts
);
789 ncs
->hnc_fcs_err
= ntohl(rsp
->fcs_err
);
790 ncs
->hnc_align_err
= ntohl(rsp
->align_err
);
791 ncs
->hnc_false_carrier
= ntohl(rsp
->false_carrier
);
792 ncs
->hnc_runt_pkts
= ntohl(rsp
->runt_pkts
);
793 ncs
->hnc_jabber_pkts
= ntohl(rsp
->jabber_pkts
);
794 ncs
->hnc_rx_pause_xon
= ntohl(rsp
->rx_pause_xon
);
795 ncs
->hnc_rx_pause_xoff
= ntohl(rsp
->rx_pause_xoff
);
796 ncs
->hnc_tx_pause_xon
= ntohl(rsp
->tx_pause_xon
);
797 ncs
->hnc_tx_pause_xoff
= ntohl(rsp
->tx_pause_xoff
);
798 ncs
->hnc_tx_s_collision
= ntohl(rsp
->tx_s_collision
);
799 ncs
->hnc_tx_m_collision
= ntohl(rsp
->tx_m_collision
);
800 ncs
->hnc_l_collision
= ntohl(rsp
->l_collision
);
801 ncs
->hnc_e_collision
= ntohl(rsp
->e_collision
);
802 ncs
->hnc_rx_ctl_frames
= ntohl(rsp
->rx_ctl_frames
);
803 ncs
->hnc_rx_64_frames
= ntohl(rsp
->rx_64_frames
);
804 ncs
->hnc_rx_127_frames
= ntohl(rsp
->rx_127_frames
);
805 ncs
->hnc_rx_255_frames
= ntohl(rsp
->rx_255_frames
);
806 ncs
->hnc_rx_511_frames
= ntohl(rsp
->rx_511_frames
);
807 ncs
->hnc_rx_1023_frames
= ntohl(rsp
->rx_1023_frames
);
808 ncs
->hnc_rx_1522_frames
= ntohl(rsp
->rx_1522_frames
);
809 ncs
->hnc_rx_9022_frames
= ntohl(rsp
->rx_9022_frames
);
810 ncs
->hnc_tx_64_frames
= ntohl(rsp
->tx_64_frames
);
811 ncs
->hnc_tx_127_frames
= ntohl(rsp
->tx_127_frames
);
812 ncs
->hnc_tx_255_frames
= ntohl(rsp
->tx_255_frames
);
813 ncs
->hnc_tx_511_frames
= ntohl(rsp
->tx_511_frames
);
814 ncs
->hnc_tx_1023_frames
= ntohl(rsp
->tx_1023_frames
);
815 ncs
->hnc_tx_1522_frames
= ntohl(rsp
->tx_1522_frames
);
816 ncs
->hnc_tx_9022_frames
= ntohl(rsp
->tx_9022_frames
);
817 ncs
->hnc_rx_valid_bytes
= ntohl(rsp
->rx_valid_bytes
);
818 ncs
->hnc_rx_runt_pkts
= ntohl(rsp
->rx_runt_pkts
);
819 ncs
->hnc_rx_jabber_pkts
= ntohl(rsp
->rx_jabber_pkts
);
824 static int ncsi_rsp_handler_gns(struct ncsi_request
*nr
)
826 struct ncsi_rsp_gns_pkt
*rsp
;
827 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
828 struct ncsi_channel
*nc
;
829 struct ncsi_channel_stats
*ncs
;
831 /* Find the channel */
832 rsp
= (struct ncsi_rsp_gns_pkt
*)skb_network_header(nr
->rsp
);
833 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
838 /* Update HNC's statistics */
840 ncs
->ncsi_rx_cmds
= ntohl(rsp
->rx_cmds
);
841 ncs
->ncsi_dropped_cmds
= ntohl(rsp
->dropped_cmds
);
842 ncs
->ncsi_cmd_type_errs
= ntohl(rsp
->cmd_type_errs
);
843 ncs
->ncsi_cmd_csum_errs
= ntohl(rsp
->cmd_csum_errs
);
844 ncs
->ncsi_rx_pkts
= ntohl(rsp
->rx_pkts
);
845 ncs
->ncsi_tx_pkts
= ntohl(rsp
->tx_pkts
);
846 ncs
->ncsi_tx_aen_pkts
= ntohl(rsp
->tx_aen_pkts
);
851 static int ncsi_rsp_handler_gnpts(struct ncsi_request
*nr
)
853 struct ncsi_rsp_gnpts_pkt
*rsp
;
854 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
855 struct ncsi_channel
*nc
;
856 struct ncsi_channel_stats
*ncs
;
858 /* Find the channel */
859 rsp
= (struct ncsi_rsp_gnpts_pkt
*)skb_network_header(nr
->rsp
);
860 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
865 /* Update HNC's statistics */
867 ncs
->pt_tx_pkts
= ntohl(rsp
->tx_pkts
);
868 ncs
->pt_tx_dropped
= ntohl(rsp
->tx_dropped
);
869 ncs
->pt_tx_channel_err
= ntohl(rsp
->tx_channel_err
);
870 ncs
->pt_tx_us_err
= ntohl(rsp
->tx_us_err
);
871 ncs
->pt_rx_pkts
= ntohl(rsp
->rx_pkts
);
872 ncs
->pt_rx_dropped
= ntohl(rsp
->rx_dropped
);
873 ncs
->pt_rx_channel_err
= ntohl(rsp
->rx_channel_err
);
874 ncs
->pt_rx_us_err
= ntohl(rsp
->rx_us_err
);
875 ncs
->pt_rx_os_err
= ntohl(rsp
->rx_os_err
);
880 static int ncsi_rsp_handler_gps(struct ncsi_request
*nr
)
882 struct ncsi_rsp_gps_pkt
*rsp
;
883 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
884 struct ncsi_package
*np
;
886 /* Find the package */
887 rsp
= (struct ncsi_rsp_gps_pkt
*)skb_network_header(nr
->rsp
);
888 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
896 static int ncsi_rsp_handler_gpuuid(struct ncsi_request
*nr
)
898 struct ncsi_rsp_gpuuid_pkt
*rsp
;
899 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
900 struct ncsi_package
*np
;
902 /* Find the package */
903 rsp
= (struct ncsi_rsp_gpuuid_pkt
*)skb_network_header(nr
->rsp
);
904 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
909 memcpy(np
->uuid
, rsp
->uuid
, sizeof(rsp
->uuid
));
914 static struct ncsi_rsp_handler
{
917 int (*handler
)(struct ncsi_request
*nr
);
918 } ncsi_rsp_handlers
[] = {
919 { NCSI_PKT_RSP_CIS
, 4, ncsi_rsp_handler_cis
},
920 { NCSI_PKT_RSP_SP
, 4, ncsi_rsp_handler_sp
},
921 { NCSI_PKT_RSP_DP
, 4, ncsi_rsp_handler_dp
},
922 { NCSI_PKT_RSP_EC
, 4, ncsi_rsp_handler_ec
},
923 { NCSI_PKT_RSP_DC
, 4, ncsi_rsp_handler_dc
},
924 { NCSI_PKT_RSP_RC
, 4, ncsi_rsp_handler_rc
},
925 { NCSI_PKT_RSP_ECNT
, 4, ncsi_rsp_handler_ecnt
},
926 { NCSI_PKT_RSP_DCNT
, 4, ncsi_rsp_handler_dcnt
},
927 { NCSI_PKT_RSP_AE
, 4, ncsi_rsp_handler_ae
},
928 { NCSI_PKT_RSP_SL
, 4, ncsi_rsp_handler_sl
},
929 { NCSI_PKT_RSP_GLS
, 16, ncsi_rsp_handler_gls
},
930 { NCSI_PKT_RSP_SVF
, 4, ncsi_rsp_handler_svf
},
931 { NCSI_PKT_RSP_EV
, 4, ncsi_rsp_handler_ev
},
932 { NCSI_PKT_RSP_DV
, 4, ncsi_rsp_handler_dv
},
933 { NCSI_PKT_RSP_SMA
, 4, ncsi_rsp_handler_sma
},
934 { NCSI_PKT_RSP_EBF
, 4, ncsi_rsp_handler_ebf
},
935 { NCSI_PKT_RSP_DBF
, 4, ncsi_rsp_handler_dbf
},
936 { NCSI_PKT_RSP_EGMF
, 4, ncsi_rsp_handler_egmf
},
937 { NCSI_PKT_RSP_DGMF
, 4, ncsi_rsp_handler_dgmf
},
938 { NCSI_PKT_RSP_SNFC
, 4, ncsi_rsp_handler_snfc
},
939 { NCSI_PKT_RSP_GVI
, 36, ncsi_rsp_handler_gvi
},
940 { NCSI_PKT_RSP_GC
, 32, ncsi_rsp_handler_gc
},
941 { NCSI_PKT_RSP_GP
, -1, ncsi_rsp_handler_gp
},
942 { NCSI_PKT_RSP_GCPS
, 172, ncsi_rsp_handler_gcps
},
943 { NCSI_PKT_RSP_GNS
, 172, ncsi_rsp_handler_gns
},
944 { NCSI_PKT_RSP_GNPTS
, 172, ncsi_rsp_handler_gnpts
},
945 { NCSI_PKT_RSP_GPS
, 8, ncsi_rsp_handler_gps
},
946 { NCSI_PKT_RSP_OEM
, 0, NULL
},
947 { NCSI_PKT_RSP_PLDM
, 0, NULL
},
948 { NCSI_PKT_RSP_GPUUID
, 20, ncsi_rsp_handler_gpuuid
}
951 int ncsi_rcv_rsp(struct sk_buff
*skb
, struct net_device
*dev
,
952 struct packet_type
*pt
, struct net_device
*orig_dev
)
954 struct ncsi_rsp_handler
*nrh
= NULL
;
956 struct ncsi_dev_priv
*ndp
;
957 struct ncsi_request
*nr
;
958 struct ncsi_pkt_hdr
*hdr
;
962 /* Find the NCSI device */
963 nd
= ncsi_find_dev(dev
);
964 ndp
= nd
? TO_NCSI_DEV_PRIV(nd
) : NULL
;
968 /* Find the handler */
969 hdr
= (struct ncsi_pkt_hdr
*)skb_network_header(skb
);
970 for (i
= 0; i
< ARRAY_SIZE(ncsi_rsp_handlers
); i
++) {
971 if (ncsi_rsp_handlers
[i
].type
== hdr
->type
) {
972 if (ncsi_rsp_handlers
[i
].handler
)
973 nrh
= &ncsi_rsp_handlers
[i
];
982 netdev_err(nd
->dev
, "Received unrecognized packet (0x%x)\n",
987 /* Associate with the request */
988 spin_lock_irqsave(&ndp
->lock
, flags
);
989 nr
= &ndp
->requests
[hdr
->id
];
991 spin_unlock_irqrestore(&ndp
->lock
, flags
);
997 spin_unlock_irqrestore(&ndp
->lock
, flags
);
1002 /* Validate the packet */
1003 spin_unlock_irqrestore(&ndp
->lock
, flags
);
1004 payload
= nrh
->payload
;
1006 payload
= ntohs(hdr
->length
);
1007 ret
= ncsi_validate_rsp_pkt(nr
, payload
);
1011 /* Process the packet */
1012 ret
= nrh
->handler(nr
);
1014 ncsi_free_request(nr
);
This page took 0.079387 seconds and 6 git commands to generate.