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 if (ndp
->flags
& NCSI_DEV_PROBED
)
75 id
= NCSI_CHANNEL_INDEX(rsp
->rsp
.common
.channel
);
76 nc
= ncsi_add_channel(np
, id
);
79 return nc
? 0 : -ENODEV
;
82 static int ncsi_rsp_handler_sp(struct ncsi_request
*nr
)
84 struct ncsi_rsp_pkt
*rsp
;
85 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
86 struct ncsi_package
*np
;
89 /* Add the package if it's not existing. Otherwise,
90 * to change the state of its child channels.
92 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
93 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
96 if (ndp
->flags
& NCSI_DEV_PROBED
)
99 id
= NCSI_PACKAGE_INDEX(rsp
->rsp
.common
.channel
);
100 np
= ncsi_add_package(ndp
, id
);
108 static int ncsi_rsp_handler_dp(struct ncsi_request
*nr
)
110 struct ncsi_rsp_pkt
*rsp
;
111 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
112 struct ncsi_package
*np
;
113 struct ncsi_channel
*nc
;
116 /* Find the package */
117 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
118 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
123 /* Change state of all channels attached to the package */
124 NCSI_FOR_EACH_CHANNEL(np
, nc
) {
125 spin_lock_irqsave(&nc
->lock
, flags
);
126 nc
->state
= NCSI_CHANNEL_INACTIVE
;
127 spin_unlock_irqrestore(&nc
->lock
, flags
);
133 static int ncsi_rsp_handler_ec(struct ncsi_request
*nr
)
135 struct ncsi_rsp_pkt
*rsp
;
136 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
137 struct ncsi_channel
*nc
;
138 struct ncsi_channel_mode
*ncm
;
140 /* Find the package and channel */
141 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
142 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
147 ncm
= &nc
->modes
[NCSI_MODE_ENABLE
];
155 static int ncsi_rsp_handler_dc(struct ncsi_request
*nr
)
157 struct ncsi_rsp_pkt
*rsp
;
158 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
159 struct ncsi_channel
*nc
;
160 struct ncsi_channel_mode
*ncm
;
163 ret
= ncsi_validate_rsp_pkt(nr
, 4);
167 /* Find the package and channel */
168 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
169 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
174 ncm
= &nc
->modes
[NCSI_MODE_ENABLE
];
182 static int ncsi_rsp_handler_rc(struct ncsi_request
*nr
)
184 struct ncsi_rsp_pkt
*rsp
;
185 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
186 struct ncsi_channel
*nc
;
189 /* Find the package and channel */
190 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
191 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
196 /* Update state for the specified channel */
197 spin_lock_irqsave(&nc
->lock
, flags
);
198 nc
->state
= NCSI_CHANNEL_INACTIVE
;
199 spin_unlock_irqrestore(&nc
->lock
, flags
);
204 static int ncsi_rsp_handler_ecnt(struct ncsi_request
*nr
)
206 struct ncsi_rsp_pkt
*rsp
;
207 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
208 struct ncsi_channel
*nc
;
209 struct ncsi_channel_mode
*ncm
;
211 /* Find the package and channel */
212 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
213 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
218 ncm
= &nc
->modes
[NCSI_MODE_TX_ENABLE
];
226 static int ncsi_rsp_handler_dcnt(struct ncsi_request
*nr
)
228 struct ncsi_rsp_pkt
*rsp
;
229 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
230 struct ncsi_channel
*nc
;
231 struct ncsi_channel_mode
*ncm
;
233 /* Find the package and channel */
234 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
235 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
240 ncm
= &nc
->modes
[NCSI_MODE_TX_ENABLE
];
248 static int ncsi_rsp_handler_ae(struct ncsi_request
*nr
)
250 struct ncsi_cmd_ae_pkt
*cmd
;
251 struct ncsi_rsp_pkt
*rsp
;
252 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
253 struct ncsi_channel
*nc
;
254 struct ncsi_channel_mode
*ncm
;
256 /* Find the package and channel */
257 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
258 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
263 /* Check if the AEN has been enabled */
264 ncm
= &nc
->modes
[NCSI_MODE_AEN
];
268 /* Update to AEN configuration */
269 cmd
= (struct ncsi_cmd_ae_pkt
*)skb_network_header(nr
->cmd
);
271 ncm
->data
[0] = cmd
->mc_id
;
272 ncm
->data
[1] = ntohl(cmd
->mode
);
277 static int ncsi_rsp_handler_sl(struct ncsi_request
*nr
)
279 struct ncsi_cmd_sl_pkt
*cmd
;
280 struct ncsi_rsp_pkt
*rsp
;
281 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
282 struct ncsi_channel
*nc
;
283 struct ncsi_channel_mode
*ncm
;
285 /* Find the package and channel */
286 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
287 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
292 cmd
= (struct ncsi_cmd_sl_pkt
*)skb_network_header(nr
->cmd
);
293 ncm
= &nc
->modes
[NCSI_MODE_LINK
];
294 ncm
->data
[0] = ntohl(cmd
->mode
);
295 ncm
->data
[1] = ntohl(cmd
->oem_mode
);
300 static int ncsi_rsp_handler_gls(struct ncsi_request
*nr
)
302 struct ncsi_rsp_gls_pkt
*rsp
;
303 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
304 struct ncsi_channel
*nc
;
305 struct ncsi_channel_mode
*ncm
;
308 /* Find the package and channel */
309 rsp
= (struct ncsi_rsp_gls_pkt
*)skb_network_header(nr
->rsp
);
310 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
315 ncm
= &nc
->modes
[NCSI_MODE_LINK
];
316 ncm
->data
[2] = ntohl(rsp
->status
);
317 ncm
->data
[3] = ntohl(rsp
->other
);
318 ncm
->data
[4] = ntohl(rsp
->oem_status
);
320 if (nr
->flags
& NCSI_REQ_FLAG_EVENT_DRIVEN
)
323 /* Reset the channel monitor if it has been enabled */
324 spin_lock_irqsave(&nc
->lock
, flags
);
325 nc
->monitor
.state
= NCSI_CHANNEL_MONITOR_START
;
326 spin_unlock_irqrestore(&nc
->lock
, flags
);
331 static int ncsi_rsp_handler_svf(struct ncsi_request
*nr
)
333 struct ncsi_cmd_svf_pkt
*cmd
;
334 struct ncsi_rsp_pkt
*rsp
;
335 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
336 struct ncsi_channel
*nc
;
337 struct ncsi_channel_vlan_filter
*ncf
;
341 /* Find the package and channel */
342 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
343 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
348 cmd
= (struct ncsi_cmd_svf_pkt
*)skb_network_header(nr
->cmd
);
349 ncf
= &nc
->vlan_filter
;
350 if (cmd
->index
== 0 || cmd
->index
> ncf
->n_vids
)
353 /* Add or remove the VLAN filter. Remember HW indexes from 1 */
354 spin_lock_irqsave(&nc
->lock
, flags
);
355 bitmap
= &ncf
->bitmap
;
356 if (!(cmd
->enable
& 0x1)) {
357 if (test_and_clear_bit(cmd
->index
- 1, bitmap
))
358 ncf
->vids
[cmd
->index
- 1] = 0;
360 set_bit(cmd
->index
- 1, bitmap
);
361 ncf
->vids
[cmd
->index
- 1] = ntohs(cmd
->vlan
);
363 spin_unlock_irqrestore(&nc
->lock
, flags
);
368 static int ncsi_rsp_handler_ev(struct ncsi_request
*nr
)
370 struct ncsi_cmd_ev_pkt
*cmd
;
371 struct ncsi_rsp_pkt
*rsp
;
372 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
373 struct ncsi_channel
*nc
;
374 struct ncsi_channel_mode
*ncm
;
376 /* Find the package and channel */
377 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
378 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
383 /* Check if VLAN mode has been enabled */
384 ncm
= &nc
->modes
[NCSI_MODE_VLAN
];
388 /* Update to VLAN mode */
389 cmd
= (struct ncsi_cmd_ev_pkt
*)skb_network_header(nr
->cmd
);
391 ncm
->data
[0] = ntohl(cmd
->mode
);
396 static int ncsi_rsp_handler_dv(struct ncsi_request
*nr
)
398 struct ncsi_rsp_pkt
*rsp
;
399 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
400 struct ncsi_channel
*nc
;
401 struct ncsi_channel_mode
*ncm
;
403 /* Find the package and channel */
404 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
405 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
410 /* Check if VLAN mode has been enabled */
411 ncm
= &nc
->modes
[NCSI_MODE_VLAN
];
415 /* Update to VLAN mode */
420 static int ncsi_rsp_handler_sma(struct ncsi_request
*nr
)
422 struct ncsi_cmd_sma_pkt
*cmd
;
423 struct ncsi_rsp_pkt
*rsp
;
424 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
425 struct ncsi_channel
*nc
;
426 struct ncsi_channel_mac_filter
*ncf
;
433 /* Find the package and channel */
434 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
435 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
440 /* According to NCSI spec 1.01, the mixed filter table
441 * isn't supported yet.
443 cmd
= (struct ncsi_cmd_sma_pkt
*)skb_network_header(nr
->cmd
);
444 enabled
= cmd
->at_e
& 0x1;
445 ncf
= &nc
->mac_filter
;
446 bitmap
= &ncf
->bitmap
;
448 if (cmd
->index
== 0 ||
449 cmd
->index
> ncf
->n_uc
+ ncf
->n_mc
+ ncf
->n_mixed
)
452 index
= (cmd
->index
- 1) * ETH_ALEN
;
453 spin_lock_irqsave(&nc
->lock
, flags
);
455 set_bit(cmd
->index
- 1, bitmap
);
456 memcpy(&ncf
->addrs
[index
], cmd
->mac
, ETH_ALEN
);
458 clear_bit(cmd
->index
- 1, bitmap
);
459 memset(&ncf
->addrs
[index
], 0, ETH_ALEN
);
461 spin_unlock_irqrestore(&nc
->lock
, flags
);
466 static int ncsi_rsp_handler_ebf(struct ncsi_request
*nr
)
468 struct ncsi_cmd_ebf_pkt
*cmd
;
469 struct ncsi_rsp_pkt
*rsp
;
470 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
471 struct ncsi_channel
*nc
;
472 struct ncsi_channel_mode
*ncm
;
474 /* Find the package and channel */
475 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
476 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
, NULL
, &nc
);
480 /* Check if broadcast filter has been enabled */
481 ncm
= &nc
->modes
[NCSI_MODE_BC
];
485 /* Update to broadcast filter mode */
486 cmd
= (struct ncsi_cmd_ebf_pkt
*)skb_network_header(nr
->cmd
);
488 ncm
->data
[0] = ntohl(cmd
->mode
);
493 static int ncsi_rsp_handler_dbf(struct ncsi_request
*nr
)
495 struct ncsi_rsp_pkt
*rsp
;
496 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
497 struct ncsi_channel
*nc
;
498 struct ncsi_channel_mode
*ncm
;
500 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
501 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
506 /* Check if broadcast filter isn't enabled */
507 ncm
= &nc
->modes
[NCSI_MODE_BC
];
511 /* Update to broadcast filter mode */
518 static int ncsi_rsp_handler_egmf(struct ncsi_request
*nr
)
520 struct ncsi_cmd_egmf_pkt
*cmd
;
521 struct ncsi_rsp_pkt
*rsp
;
522 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
523 struct ncsi_channel
*nc
;
524 struct ncsi_channel_mode
*ncm
;
526 /* Find the channel */
527 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
528 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
533 /* Check if multicast filter has been enabled */
534 ncm
= &nc
->modes
[NCSI_MODE_MC
];
538 /* Update to multicast filter mode */
539 cmd
= (struct ncsi_cmd_egmf_pkt
*)skb_network_header(nr
->cmd
);
541 ncm
->data
[0] = ntohl(cmd
->mode
);
546 static int ncsi_rsp_handler_dgmf(struct ncsi_request
*nr
)
548 struct ncsi_rsp_pkt
*rsp
;
549 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
550 struct ncsi_channel
*nc
;
551 struct ncsi_channel_mode
*ncm
;
553 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
554 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
559 /* Check if multicast filter has been enabled */
560 ncm
= &nc
->modes
[NCSI_MODE_MC
];
564 /* Update to multicast filter mode */
571 static int ncsi_rsp_handler_snfc(struct ncsi_request
*nr
)
573 struct ncsi_cmd_snfc_pkt
*cmd
;
574 struct ncsi_rsp_pkt
*rsp
;
575 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
576 struct ncsi_channel
*nc
;
577 struct ncsi_channel_mode
*ncm
;
579 /* Find the channel */
580 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
581 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
586 /* Check if flow control has been enabled */
587 ncm
= &nc
->modes
[NCSI_MODE_FC
];
591 /* Update to flow control mode */
592 cmd
= (struct ncsi_cmd_snfc_pkt
*)skb_network_header(nr
->cmd
);
594 ncm
->data
[0] = cmd
->mode
;
599 static int ncsi_rsp_handler_gvi(struct ncsi_request
*nr
)
601 struct ncsi_rsp_gvi_pkt
*rsp
;
602 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
603 struct ncsi_channel
*nc
;
604 struct ncsi_channel_version
*ncv
;
607 /* Find the channel */
608 rsp
= (struct ncsi_rsp_gvi_pkt
*)skb_network_header(nr
->rsp
);
609 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
614 /* Update to channel's version info */
616 ncv
->version
= ntohl(rsp
->ncsi_version
);
617 ncv
->alpha2
= rsp
->alpha2
;
618 memcpy(ncv
->fw_name
, rsp
->fw_name
, 12);
619 ncv
->fw_version
= ntohl(rsp
->fw_version
);
620 for (i
= 0; i
< ARRAY_SIZE(ncv
->pci_ids
); i
++)
621 ncv
->pci_ids
[i
] = ntohs(rsp
->pci_ids
[i
]);
622 ncv
->mf_id
= ntohl(rsp
->mf_id
);
627 static int ncsi_rsp_handler_gc(struct ncsi_request
*nr
)
629 struct ncsi_rsp_gc_pkt
*rsp
;
630 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
631 struct ncsi_channel
*nc
;
634 /* Find the channel */
635 rsp
= (struct ncsi_rsp_gc_pkt
*)skb_network_header(nr
->rsp
);
636 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
641 /* Update channel's capabilities */
642 nc
->caps
[NCSI_CAP_GENERIC
].cap
= ntohl(rsp
->cap
) &
643 NCSI_CAP_GENERIC_MASK
;
644 nc
->caps
[NCSI_CAP_BC
].cap
= ntohl(rsp
->bc_cap
) &
646 nc
->caps
[NCSI_CAP_MC
].cap
= ntohl(rsp
->mc_cap
) &
648 nc
->caps
[NCSI_CAP_BUFFER
].cap
= ntohl(rsp
->buf_cap
);
649 nc
->caps
[NCSI_CAP_AEN
].cap
= ntohl(rsp
->aen_cap
) &
651 nc
->caps
[NCSI_CAP_VLAN
].cap
= rsp
->vlan_mode
&
654 size
= (rsp
->uc_cnt
+ rsp
->mc_cnt
+ rsp
->mixed_cnt
) * ETH_ALEN
;
655 nc
->mac_filter
.addrs
= kzalloc(size
, GFP_ATOMIC
);
656 if (!nc
->mac_filter
.addrs
)
658 nc
->mac_filter
.n_uc
= rsp
->uc_cnt
;
659 nc
->mac_filter
.n_mc
= rsp
->mc_cnt
;
660 nc
->mac_filter
.n_mixed
= rsp
->mixed_cnt
;
662 nc
->vlan_filter
.vids
= kcalloc(rsp
->vlan_cnt
,
663 sizeof(*nc
->vlan_filter
.vids
),
665 if (!nc
->vlan_filter
.vids
)
667 /* Set VLAN filters active so they are cleared in the first
668 * configuration state
670 nc
->vlan_filter
.bitmap
= U64_MAX
;
671 nc
->vlan_filter
.n_vids
= rsp
->vlan_cnt
;
676 static int ncsi_rsp_handler_gp(struct ncsi_request
*nr
)
678 struct ncsi_channel_vlan_filter
*ncvf
;
679 struct ncsi_channel_mac_filter
*ncmf
;
680 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
681 struct ncsi_rsp_gp_pkt
*rsp
;
682 struct ncsi_channel
*nc
;
683 unsigned short enable
;
684 unsigned char *pdata
;
689 /* Find the channel */
690 rsp
= (struct ncsi_rsp_gp_pkt
*)skb_network_header(nr
->rsp
);
691 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
696 /* Modes with explicit enabled indications */
697 if (ntohl(rsp
->valid_modes
) & 0x1) { /* BC filter mode */
698 nc
->modes
[NCSI_MODE_BC
].enable
= 1;
699 nc
->modes
[NCSI_MODE_BC
].data
[0] = ntohl(rsp
->bc_mode
);
701 if (ntohl(rsp
->valid_modes
) & 0x2) /* Channel enabled */
702 nc
->modes
[NCSI_MODE_ENABLE
].enable
= 1;
703 if (ntohl(rsp
->valid_modes
) & 0x4) /* Channel Tx enabled */
704 nc
->modes
[NCSI_MODE_TX_ENABLE
].enable
= 1;
705 if (ntohl(rsp
->valid_modes
) & 0x8) /* MC filter mode */
706 nc
->modes
[NCSI_MODE_MC
].enable
= 1;
708 /* Modes without explicit enabled indications */
709 nc
->modes
[NCSI_MODE_LINK
].enable
= 1;
710 nc
->modes
[NCSI_MODE_LINK
].data
[0] = ntohl(rsp
->link_mode
);
711 nc
->modes
[NCSI_MODE_VLAN
].enable
= 1;
712 nc
->modes
[NCSI_MODE_VLAN
].data
[0] = rsp
->vlan_mode
;
713 nc
->modes
[NCSI_MODE_FC
].enable
= 1;
714 nc
->modes
[NCSI_MODE_FC
].data
[0] = rsp
->fc_mode
;
715 nc
->modes
[NCSI_MODE_AEN
].enable
= 1;
716 nc
->modes
[NCSI_MODE_AEN
].data
[0] = ntohl(rsp
->aen_mode
);
718 /* MAC addresses filter table */
719 pdata
= (unsigned char *)rsp
+ 48;
720 enable
= rsp
->mac_enable
;
721 ncmf
= &nc
->mac_filter
;
722 spin_lock_irqsave(&nc
->lock
, flags
);
723 bitmap
= &ncmf
->bitmap
;
724 for (i
= 0; i
< rsp
->mac_cnt
; i
++, pdata
+= 6) {
725 if (!(enable
& (0x1 << i
)))
726 clear_bit(i
, bitmap
);
730 memcpy(&ncmf
->addrs
[i
* ETH_ALEN
], pdata
, ETH_ALEN
);
732 spin_unlock_irqrestore(&nc
->lock
, flags
);
734 /* VLAN filter table */
735 enable
= ntohs(rsp
->vlan_enable
);
736 ncvf
= &nc
->vlan_filter
;
737 bitmap
= &ncvf
->bitmap
;
738 spin_lock_irqsave(&nc
->lock
, flags
);
739 for (i
= 0; i
< rsp
->vlan_cnt
; i
++, pdata
+= 2) {
740 if (!(enable
& (0x1 << i
)))
741 clear_bit(i
, bitmap
);
745 ncvf
->vids
[i
] = ntohs(*(__be16
*)pdata
);
747 spin_unlock_irqrestore(&nc
->lock
, flags
);
752 static int ncsi_rsp_handler_gcps(struct ncsi_request
*nr
)
754 struct ncsi_rsp_gcps_pkt
*rsp
;
755 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
756 struct ncsi_channel
*nc
;
757 struct ncsi_channel_stats
*ncs
;
759 /* Find the channel */
760 rsp
= (struct ncsi_rsp_gcps_pkt
*)skb_network_header(nr
->rsp
);
761 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
766 /* Update HNC's statistics */
768 ncs
->hnc_cnt_hi
= ntohl(rsp
->cnt_hi
);
769 ncs
->hnc_cnt_lo
= ntohl(rsp
->cnt_lo
);
770 ncs
->hnc_rx_bytes
= ntohl(rsp
->rx_bytes
);
771 ncs
->hnc_tx_bytes
= ntohl(rsp
->tx_bytes
);
772 ncs
->hnc_rx_uc_pkts
= ntohl(rsp
->rx_uc_pkts
);
773 ncs
->hnc_rx_mc_pkts
= ntohl(rsp
->rx_mc_pkts
);
774 ncs
->hnc_rx_bc_pkts
= ntohl(rsp
->rx_bc_pkts
);
775 ncs
->hnc_tx_uc_pkts
= ntohl(rsp
->tx_uc_pkts
);
776 ncs
->hnc_tx_mc_pkts
= ntohl(rsp
->tx_mc_pkts
);
777 ncs
->hnc_tx_bc_pkts
= ntohl(rsp
->tx_bc_pkts
);
778 ncs
->hnc_fcs_err
= ntohl(rsp
->fcs_err
);
779 ncs
->hnc_align_err
= ntohl(rsp
->align_err
);
780 ncs
->hnc_false_carrier
= ntohl(rsp
->false_carrier
);
781 ncs
->hnc_runt_pkts
= ntohl(rsp
->runt_pkts
);
782 ncs
->hnc_jabber_pkts
= ntohl(rsp
->jabber_pkts
);
783 ncs
->hnc_rx_pause_xon
= ntohl(rsp
->rx_pause_xon
);
784 ncs
->hnc_rx_pause_xoff
= ntohl(rsp
->rx_pause_xoff
);
785 ncs
->hnc_tx_pause_xon
= ntohl(rsp
->tx_pause_xon
);
786 ncs
->hnc_tx_pause_xoff
= ntohl(rsp
->tx_pause_xoff
);
787 ncs
->hnc_tx_s_collision
= ntohl(rsp
->tx_s_collision
);
788 ncs
->hnc_tx_m_collision
= ntohl(rsp
->tx_m_collision
);
789 ncs
->hnc_l_collision
= ntohl(rsp
->l_collision
);
790 ncs
->hnc_e_collision
= ntohl(rsp
->e_collision
);
791 ncs
->hnc_rx_ctl_frames
= ntohl(rsp
->rx_ctl_frames
);
792 ncs
->hnc_rx_64_frames
= ntohl(rsp
->rx_64_frames
);
793 ncs
->hnc_rx_127_frames
= ntohl(rsp
->rx_127_frames
);
794 ncs
->hnc_rx_255_frames
= ntohl(rsp
->rx_255_frames
);
795 ncs
->hnc_rx_511_frames
= ntohl(rsp
->rx_511_frames
);
796 ncs
->hnc_rx_1023_frames
= ntohl(rsp
->rx_1023_frames
);
797 ncs
->hnc_rx_1522_frames
= ntohl(rsp
->rx_1522_frames
);
798 ncs
->hnc_rx_9022_frames
= ntohl(rsp
->rx_9022_frames
);
799 ncs
->hnc_tx_64_frames
= ntohl(rsp
->tx_64_frames
);
800 ncs
->hnc_tx_127_frames
= ntohl(rsp
->tx_127_frames
);
801 ncs
->hnc_tx_255_frames
= ntohl(rsp
->tx_255_frames
);
802 ncs
->hnc_tx_511_frames
= ntohl(rsp
->tx_511_frames
);
803 ncs
->hnc_tx_1023_frames
= ntohl(rsp
->tx_1023_frames
);
804 ncs
->hnc_tx_1522_frames
= ntohl(rsp
->tx_1522_frames
);
805 ncs
->hnc_tx_9022_frames
= ntohl(rsp
->tx_9022_frames
);
806 ncs
->hnc_rx_valid_bytes
= ntohl(rsp
->rx_valid_bytes
);
807 ncs
->hnc_rx_runt_pkts
= ntohl(rsp
->rx_runt_pkts
);
808 ncs
->hnc_rx_jabber_pkts
= ntohl(rsp
->rx_jabber_pkts
);
813 static int ncsi_rsp_handler_gns(struct ncsi_request
*nr
)
815 struct ncsi_rsp_gns_pkt
*rsp
;
816 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
817 struct ncsi_channel
*nc
;
818 struct ncsi_channel_stats
*ncs
;
820 /* Find the channel */
821 rsp
= (struct ncsi_rsp_gns_pkt
*)skb_network_header(nr
->rsp
);
822 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
827 /* Update HNC's statistics */
829 ncs
->ncsi_rx_cmds
= ntohl(rsp
->rx_cmds
);
830 ncs
->ncsi_dropped_cmds
= ntohl(rsp
->dropped_cmds
);
831 ncs
->ncsi_cmd_type_errs
= ntohl(rsp
->cmd_type_errs
);
832 ncs
->ncsi_cmd_csum_errs
= ntohl(rsp
->cmd_csum_errs
);
833 ncs
->ncsi_rx_pkts
= ntohl(rsp
->rx_pkts
);
834 ncs
->ncsi_tx_pkts
= ntohl(rsp
->tx_pkts
);
835 ncs
->ncsi_tx_aen_pkts
= ntohl(rsp
->tx_aen_pkts
);
840 static int ncsi_rsp_handler_gnpts(struct ncsi_request
*nr
)
842 struct ncsi_rsp_gnpts_pkt
*rsp
;
843 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
844 struct ncsi_channel
*nc
;
845 struct ncsi_channel_stats
*ncs
;
847 /* Find the channel */
848 rsp
= (struct ncsi_rsp_gnpts_pkt
*)skb_network_header(nr
->rsp
);
849 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
854 /* Update HNC's statistics */
856 ncs
->pt_tx_pkts
= ntohl(rsp
->tx_pkts
);
857 ncs
->pt_tx_dropped
= ntohl(rsp
->tx_dropped
);
858 ncs
->pt_tx_channel_err
= ntohl(rsp
->tx_channel_err
);
859 ncs
->pt_tx_us_err
= ntohl(rsp
->tx_us_err
);
860 ncs
->pt_rx_pkts
= ntohl(rsp
->rx_pkts
);
861 ncs
->pt_rx_dropped
= ntohl(rsp
->rx_dropped
);
862 ncs
->pt_rx_channel_err
= ntohl(rsp
->rx_channel_err
);
863 ncs
->pt_rx_us_err
= ntohl(rsp
->rx_us_err
);
864 ncs
->pt_rx_os_err
= ntohl(rsp
->rx_os_err
);
869 static int ncsi_rsp_handler_gps(struct ncsi_request
*nr
)
871 struct ncsi_rsp_gps_pkt
*rsp
;
872 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
873 struct ncsi_package
*np
;
875 /* Find the package */
876 rsp
= (struct ncsi_rsp_gps_pkt
*)skb_network_header(nr
->rsp
);
877 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
885 static int ncsi_rsp_handler_gpuuid(struct ncsi_request
*nr
)
887 struct ncsi_rsp_gpuuid_pkt
*rsp
;
888 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
889 struct ncsi_package
*np
;
891 /* Find the package */
892 rsp
= (struct ncsi_rsp_gpuuid_pkt
*)skb_network_header(nr
->rsp
);
893 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
898 memcpy(np
->uuid
, rsp
->uuid
, sizeof(rsp
->uuid
));
903 static struct ncsi_rsp_handler
{
906 int (*handler
)(struct ncsi_request
*nr
);
907 } ncsi_rsp_handlers
[] = {
908 { NCSI_PKT_RSP_CIS
, 4, ncsi_rsp_handler_cis
},
909 { NCSI_PKT_RSP_SP
, 4, ncsi_rsp_handler_sp
},
910 { NCSI_PKT_RSP_DP
, 4, ncsi_rsp_handler_dp
},
911 { NCSI_PKT_RSP_EC
, 4, ncsi_rsp_handler_ec
},
912 { NCSI_PKT_RSP_DC
, 4, ncsi_rsp_handler_dc
},
913 { NCSI_PKT_RSP_RC
, 4, ncsi_rsp_handler_rc
},
914 { NCSI_PKT_RSP_ECNT
, 4, ncsi_rsp_handler_ecnt
},
915 { NCSI_PKT_RSP_DCNT
, 4, ncsi_rsp_handler_dcnt
},
916 { NCSI_PKT_RSP_AE
, 4, ncsi_rsp_handler_ae
},
917 { NCSI_PKT_RSP_SL
, 4, ncsi_rsp_handler_sl
},
918 { NCSI_PKT_RSP_GLS
, 16, ncsi_rsp_handler_gls
},
919 { NCSI_PKT_RSP_SVF
, 4, ncsi_rsp_handler_svf
},
920 { NCSI_PKT_RSP_EV
, 4, ncsi_rsp_handler_ev
},
921 { NCSI_PKT_RSP_DV
, 4, ncsi_rsp_handler_dv
},
922 { NCSI_PKT_RSP_SMA
, 4, ncsi_rsp_handler_sma
},
923 { NCSI_PKT_RSP_EBF
, 4, ncsi_rsp_handler_ebf
},
924 { NCSI_PKT_RSP_DBF
, 4, ncsi_rsp_handler_dbf
},
925 { NCSI_PKT_RSP_EGMF
, 4, ncsi_rsp_handler_egmf
},
926 { NCSI_PKT_RSP_DGMF
, 4, ncsi_rsp_handler_dgmf
},
927 { NCSI_PKT_RSP_SNFC
, 4, ncsi_rsp_handler_snfc
},
928 { NCSI_PKT_RSP_GVI
, 40, ncsi_rsp_handler_gvi
},
929 { NCSI_PKT_RSP_GC
, 32, ncsi_rsp_handler_gc
},
930 { NCSI_PKT_RSP_GP
, -1, ncsi_rsp_handler_gp
},
931 { NCSI_PKT_RSP_GCPS
, 172, ncsi_rsp_handler_gcps
},
932 { NCSI_PKT_RSP_GNS
, 172, ncsi_rsp_handler_gns
},
933 { NCSI_PKT_RSP_GNPTS
, 172, ncsi_rsp_handler_gnpts
},
934 { NCSI_PKT_RSP_GPS
, 8, ncsi_rsp_handler_gps
},
935 { NCSI_PKT_RSP_OEM
, 0, NULL
},
936 { NCSI_PKT_RSP_PLDM
, 0, NULL
},
937 { NCSI_PKT_RSP_GPUUID
, 20, ncsi_rsp_handler_gpuuid
}
940 int ncsi_rcv_rsp(struct sk_buff
*skb
, struct net_device
*dev
,
941 struct packet_type
*pt
, struct net_device
*orig_dev
)
943 struct ncsi_rsp_handler
*nrh
= NULL
;
945 struct ncsi_dev_priv
*ndp
;
946 struct ncsi_request
*nr
;
947 struct ncsi_pkt_hdr
*hdr
;
951 /* Find the NCSI device */
952 nd
= ncsi_find_dev(dev
);
953 ndp
= nd
? TO_NCSI_DEV_PRIV(nd
) : NULL
;
957 /* Check if it is AEN packet */
958 hdr
= (struct ncsi_pkt_hdr
*)skb_network_header(skb
);
959 if (hdr
->type
== NCSI_PKT_AEN
)
960 return ncsi_aen_handler(ndp
, skb
);
962 /* Find the handler */
963 for (i
= 0; i
< ARRAY_SIZE(ncsi_rsp_handlers
); i
++) {
964 if (ncsi_rsp_handlers
[i
].type
== hdr
->type
) {
965 if (ncsi_rsp_handlers
[i
].handler
)
966 nrh
= &ncsi_rsp_handlers
[i
];
975 netdev_err(nd
->dev
, "Received unrecognized packet (0x%x)\n",
980 /* Associate with the request */
981 spin_lock_irqsave(&ndp
->lock
, flags
);
982 nr
= &ndp
->requests
[hdr
->id
];
984 spin_unlock_irqrestore(&ndp
->lock
, flags
);
990 spin_unlock_irqrestore(&ndp
->lock
, flags
);
995 /* Validate the packet */
996 spin_unlock_irqrestore(&ndp
->lock
, flags
);
997 payload
= nrh
->payload
;
999 payload
= ntohs(hdr
->length
);
1000 ret
= ncsi_validate_rsp_pkt(nr
, payload
);
1002 netdev_warn(ndp
->ndev
.dev
,
1003 "NCSI: 'bad' packet ignored for type 0x%x\n",
1008 /* Process the packet */
1009 ret
= nrh
->handler(nr
);
1011 netdev_err(ndp
->ndev
.dev
,
1012 "NCSI: Handler for packet type 0x%x returned %d\n",
1015 ncsi_free_request(nr
);