1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright Gavin Shan, IBM Corporation 2016.
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>
14 #include <net/net_namespace.h>
16 #include <net/genetlink.h>
20 #include "ncsi-netlink.h"
22 static int ncsi_validate_rsp_pkt(struct ncsi_request
*nr
,
23 unsigned short payload
)
25 struct ncsi_rsp_pkt_hdr
*h
;
29 /* Check NCSI packet header. We don't need validate
30 * the packet type, which should have been checked
31 * before calling this function.
33 h
= (struct ncsi_rsp_pkt_hdr
*)skb_network_header(nr
->rsp
);
35 if (h
->common
.revision
!= NCSI_PKT_REVISION
) {
36 netdev_dbg(nr
->ndp
->ndev
.dev
,
37 "NCSI: unsupported header revision\n");
40 if (ntohs(h
->common
.length
) != payload
) {
41 netdev_dbg(nr
->ndp
->ndev
.dev
,
42 "NCSI: payload length mismatched\n");
46 /* Check on code and reason */
47 if (ntohs(h
->code
) != NCSI_PKT_RSP_C_COMPLETED
||
48 ntohs(h
->reason
) != NCSI_PKT_RSP_R_NO_ERROR
) {
49 netdev_dbg(nr
->ndp
->ndev
.dev
,
50 "NCSI: non zero response/reason code %04xh, %04xh\n",
51 ntohs(h
->code
), ntohs(h
->reason
));
55 /* Validate checksum, which might be zeroes if the
56 * sender doesn't support checksum according to NCSI
59 pchecksum
= (__be32
*)((void *)(h
+ 1) + ALIGN(payload
, 4) - 4);
60 if (ntohl(*pchecksum
) == 0)
63 checksum
= ncsi_calculate_checksum((unsigned char *)h
,
64 sizeof(*h
) + payload
- 4);
66 if (*pchecksum
!= htonl(checksum
)) {
67 netdev_dbg(nr
->ndp
->ndev
.dev
,
68 "NCSI: checksum mismatched; recd: %08x calc: %08x\n",
69 *pchecksum
, htonl(checksum
));
76 static int ncsi_rsp_handler_cis(struct ncsi_request
*nr
)
78 struct ncsi_rsp_pkt
*rsp
;
79 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
80 struct ncsi_package
*np
;
81 struct ncsi_channel
*nc
;
84 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
85 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
, &np
, &nc
);
87 if (ndp
->flags
& NCSI_DEV_PROBED
)
90 id
= NCSI_CHANNEL_INDEX(rsp
->rsp
.common
.channel
);
91 nc
= ncsi_add_channel(np
, id
);
94 return nc
? 0 : -ENODEV
;
97 static int ncsi_rsp_handler_sp(struct ncsi_request
*nr
)
99 struct ncsi_rsp_pkt
*rsp
;
100 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
101 struct ncsi_package
*np
;
104 /* Add the package if it's not existing. Otherwise,
105 * to change the state of its child channels.
107 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
108 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
111 if (ndp
->flags
& NCSI_DEV_PROBED
)
114 id
= NCSI_PACKAGE_INDEX(rsp
->rsp
.common
.channel
);
115 np
= ncsi_add_package(ndp
, id
);
123 static int ncsi_rsp_handler_dp(struct ncsi_request
*nr
)
125 struct ncsi_rsp_pkt
*rsp
;
126 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
127 struct ncsi_package
*np
;
128 struct ncsi_channel
*nc
;
131 /* Find the package */
132 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
133 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
138 /* Change state of all channels attached to the package */
139 NCSI_FOR_EACH_CHANNEL(np
, nc
) {
140 spin_lock_irqsave(&nc
->lock
, flags
);
141 nc
->state
= NCSI_CHANNEL_INACTIVE
;
142 spin_unlock_irqrestore(&nc
->lock
, flags
);
148 static int ncsi_rsp_handler_ec(struct ncsi_request
*nr
)
150 struct ncsi_rsp_pkt
*rsp
;
151 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
152 struct ncsi_channel
*nc
;
153 struct ncsi_channel_mode
*ncm
;
155 /* Find the package and channel */
156 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
157 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
162 ncm
= &nc
->modes
[NCSI_MODE_ENABLE
];
170 static int ncsi_rsp_handler_dc(struct ncsi_request
*nr
)
172 struct ncsi_rsp_pkt
*rsp
;
173 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
174 struct ncsi_channel
*nc
;
175 struct ncsi_channel_mode
*ncm
;
178 ret
= ncsi_validate_rsp_pkt(nr
, 4);
182 /* Find the package and channel */
183 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
184 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
189 ncm
= &nc
->modes
[NCSI_MODE_ENABLE
];
197 static int ncsi_rsp_handler_rc(struct ncsi_request
*nr
)
199 struct ncsi_rsp_pkt
*rsp
;
200 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
201 struct ncsi_channel
*nc
;
204 /* Find the package and channel */
205 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
206 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
211 /* Update state for the specified channel */
212 spin_lock_irqsave(&nc
->lock
, flags
);
213 nc
->state
= NCSI_CHANNEL_INACTIVE
;
214 spin_unlock_irqrestore(&nc
->lock
, flags
);
219 static int ncsi_rsp_handler_ecnt(struct ncsi_request
*nr
)
221 struct ncsi_rsp_pkt
*rsp
;
222 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
223 struct ncsi_channel
*nc
;
224 struct ncsi_channel_mode
*ncm
;
226 /* Find the package and channel */
227 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
228 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
233 ncm
= &nc
->modes
[NCSI_MODE_TX_ENABLE
];
241 static int ncsi_rsp_handler_dcnt(struct ncsi_request
*nr
)
243 struct ncsi_rsp_pkt
*rsp
;
244 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
245 struct ncsi_channel
*nc
;
246 struct ncsi_channel_mode
*ncm
;
248 /* Find the package and channel */
249 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
250 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
255 ncm
= &nc
->modes
[NCSI_MODE_TX_ENABLE
];
263 static int ncsi_rsp_handler_ae(struct ncsi_request
*nr
)
265 struct ncsi_cmd_ae_pkt
*cmd
;
266 struct ncsi_rsp_pkt
*rsp
;
267 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
268 struct ncsi_channel
*nc
;
269 struct ncsi_channel_mode
*ncm
;
271 /* Find the package and channel */
272 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
273 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
278 /* Check if the AEN has been enabled */
279 ncm
= &nc
->modes
[NCSI_MODE_AEN
];
283 /* Update to AEN configuration */
284 cmd
= (struct ncsi_cmd_ae_pkt
*)skb_network_header(nr
->cmd
);
286 ncm
->data
[0] = cmd
->mc_id
;
287 ncm
->data
[1] = ntohl(cmd
->mode
);
292 static int ncsi_rsp_handler_sl(struct ncsi_request
*nr
)
294 struct ncsi_cmd_sl_pkt
*cmd
;
295 struct ncsi_rsp_pkt
*rsp
;
296 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
297 struct ncsi_channel
*nc
;
298 struct ncsi_channel_mode
*ncm
;
300 /* Find the package and channel */
301 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
302 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
307 cmd
= (struct ncsi_cmd_sl_pkt
*)skb_network_header(nr
->cmd
);
308 ncm
= &nc
->modes
[NCSI_MODE_LINK
];
309 ncm
->data
[0] = ntohl(cmd
->mode
);
310 ncm
->data
[1] = ntohl(cmd
->oem_mode
);
315 static int ncsi_rsp_handler_gls(struct ncsi_request
*nr
)
317 struct ncsi_rsp_gls_pkt
*rsp
;
318 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
319 struct ncsi_channel
*nc
;
320 struct ncsi_channel_mode
*ncm
;
323 /* Find the package and channel */
324 rsp
= (struct ncsi_rsp_gls_pkt
*)skb_network_header(nr
->rsp
);
325 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
330 ncm
= &nc
->modes
[NCSI_MODE_LINK
];
331 ncm
->data
[2] = ntohl(rsp
->status
);
332 ncm
->data
[3] = ntohl(rsp
->other
);
333 ncm
->data
[4] = ntohl(rsp
->oem_status
);
335 if (nr
->flags
& NCSI_REQ_FLAG_EVENT_DRIVEN
)
338 /* Reset the channel monitor if it has been enabled */
339 spin_lock_irqsave(&nc
->lock
, flags
);
340 nc
->monitor
.state
= NCSI_CHANNEL_MONITOR_START
;
341 spin_unlock_irqrestore(&nc
->lock
, flags
);
346 static int ncsi_rsp_handler_svf(struct ncsi_request
*nr
)
348 struct ncsi_cmd_svf_pkt
*cmd
;
349 struct ncsi_rsp_pkt
*rsp
;
350 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
351 struct ncsi_channel
*nc
;
352 struct ncsi_channel_vlan_filter
*ncf
;
356 /* Find the package and channel */
357 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
358 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
363 cmd
= (struct ncsi_cmd_svf_pkt
*)skb_network_header(nr
->cmd
);
364 ncf
= &nc
->vlan_filter
;
365 if (cmd
->index
== 0 || cmd
->index
> ncf
->n_vids
)
368 /* Add or remove the VLAN filter. Remember HW indexes from 1 */
369 spin_lock_irqsave(&nc
->lock
, flags
);
370 bitmap
= &ncf
->bitmap
;
371 if (!(cmd
->enable
& 0x1)) {
372 if (test_and_clear_bit(cmd
->index
- 1, bitmap
))
373 ncf
->vids
[cmd
->index
- 1] = 0;
375 set_bit(cmd
->index
- 1, bitmap
);
376 ncf
->vids
[cmd
->index
- 1] = ntohs(cmd
->vlan
);
378 spin_unlock_irqrestore(&nc
->lock
, flags
);
383 static int ncsi_rsp_handler_ev(struct ncsi_request
*nr
)
385 struct ncsi_cmd_ev_pkt
*cmd
;
386 struct ncsi_rsp_pkt
*rsp
;
387 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
388 struct ncsi_channel
*nc
;
389 struct ncsi_channel_mode
*ncm
;
391 /* Find the package and channel */
392 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
393 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
398 /* Check if VLAN mode has been enabled */
399 ncm
= &nc
->modes
[NCSI_MODE_VLAN
];
403 /* Update to VLAN mode */
404 cmd
= (struct ncsi_cmd_ev_pkt
*)skb_network_header(nr
->cmd
);
406 ncm
->data
[0] = ntohl(cmd
->mode
);
411 static int ncsi_rsp_handler_dv(struct ncsi_request
*nr
)
413 struct ncsi_rsp_pkt
*rsp
;
414 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
415 struct ncsi_channel
*nc
;
416 struct ncsi_channel_mode
*ncm
;
418 /* Find the package and channel */
419 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
420 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
425 /* Check if VLAN mode has been enabled */
426 ncm
= &nc
->modes
[NCSI_MODE_VLAN
];
430 /* Update to VLAN mode */
435 static int ncsi_rsp_handler_sma(struct ncsi_request
*nr
)
437 struct ncsi_cmd_sma_pkt
*cmd
;
438 struct ncsi_rsp_pkt
*rsp
;
439 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
440 struct ncsi_channel
*nc
;
441 struct ncsi_channel_mac_filter
*ncf
;
448 /* Find the package and channel */
449 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
450 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
455 /* According to NCSI spec 1.01, the mixed filter table
456 * isn't supported yet.
458 cmd
= (struct ncsi_cmd_sma_pkt
*)skb_network_header(nr
->cmd
);
459 enabled
= cmd
->at_e
& 0x1;
460 ncf
= &nc
->mac_filter
;
461 bitmap
= &ncf
->bitmap
;
463 if (cmd
->index
== 0 ||
464 cmd
->index
> ncf
->n_uc
+ ncf
->n_mc
+ ncf
->n_mixed
)
467 index
= (cmd
->index
- 1) * ETH_ALEN
;
468 spin_lock_irqsave(&nc
->lock
, flags
);
470 set_bit(cmd
->index
- 1, bitmap
);
471 memcpy(&ncf
->addrs
[index
], cmd
->mac
, ETH_ALEN
);
473 clear_bit(cmd
->index
- 1, bitmap
);
474 eth_zero_addr(&ncf
->addrs
[index
]);
476 spin_unlock_irqrestore(&nc
->lock
, flags
);
481 static int ncsi_rsp_handler_ebf(struct ncsi_request
*nr
)
483 struct ncsi_cmd_ebf_pkt
*cmd
;
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 /* Find the package and channel */
490 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
491 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
, NULL
, &nc
);
495 /* Check if broadcast filter has been enabled */
496 ncm
= &nc
->modes
[NCSI_MODE_BC
];
500 /* Update to broadcast filter mode */
501 cmd
= (struct ncsi_cmd_ebf_pkt
*)skb_network_header(nr
->cmd
);
503 ncm
->data
[0] = ntohl(cmd
->mode
);
508 static int ncsi_rsp_handler_dbf(struct ncsi_request
*nr
)
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 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
516 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
521 /* Check if broadcast filter isn't enabled */
522 ncm
= &nc
->modes
[NCSI_MODE_BC
];
526 /* Update to broadcast filter mode */
533 static int ncsi_rsp_handler_egmf(struct ncsi_request
*nr
)
535 struct ncsi_cmd_egmf_pkt
*cmd
;
536 struct ncsi_rsp_pkt
*rsp
;
537 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
538 struct ncsi_channel
*nc
;
539 struct ncsi_channel_mode
*ncm
;
541 /* Find the channel */
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 */
554 cmd
= (struct ncsi_cmd_egmf_pkt
*)skb_network_header(nr
->cmd
);
556 ncm
->data
[0] = ntohl(cmd
->mode
);
561 static int ncsi_rsp_handler_dgmf(struct ncsi_request
*nr
)
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 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
569 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
574 /* Check if multicast filter has been enabled */
575 ncm
= &nc
->modes
[NCSI_MODE_MC
];
579 /* Update to multicast filter mode */
586 static int ncsi_rsp_handler_snfc(struct ncsi_request
*nr
)
588 struct ncsi_cmd_snfc_pkt
*cmd
;
589 struct ncsi_rsp_pkt
*rsp
;
590 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
591 struct ncsi_channel
*nc
;
592 struct ncsi_channel_mode
*ncm
;
594 /* Find the channel */
595 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
596 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
601 /* Check if flow control has been enabled */
602 ncm
= &nc
->modes
[NCSI_MODE_FC
];
606 /* Update to flow control mode */
607 cmd
= (struct ncsi_cmd_snfc_pkt
*)skb_network_header(nr
->cmd
);
609 ncm
->data
[0] = cmd
->mode
;
614 /* Response handler for Mellanox command Get Mac Address */
615 static int ncsi_rsp_handler_oem_mlx_gma(struct ncsi_request
*nr
)
617 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
618 struct net_device
*ndev
= ndp
->ndev
.dev
;
619 const struct net_device_ops
*ops
= ndev
->netdev_ops
;
620 struct ncsi_rsp_oem_pkt
*rsp
;
621 struct sockaddr saddr
;
624 /* Get the response header */
625 rsp
= (struct ncsi_rsp_oem_pkt
*)skb_network_header(nr
->rsp
);
627 saddr
.sa_family
= ndev
->type
;
628 ndev
->priv_flags
|= IFF_LIVE_ADDR_CHANGE
;
629 memcpy(saddr
.sa_data
, &rsp
->data
[MLX_MAC_ADDR_OFFSET
], ETH_ALEN
);
630 /* Set the flag for GMA command which should only be called once */
633 ret
= ops
->ndo_set_mac_address(ndev
, &saddr
);
635 netdev_warn(ndev
, "NCSI: 'Writing mac address to device failed\n");
640 /* Response handler for Mellanox card */
641 static int ncsi_rsp_handler_oem_mlx(struct ncsi_request
*nr
)
643 struct ncsi_rsp_oem_mlx_pkt
*mlx
;
644 struct ncsi_rsp_oem_pkt
*rsp
;
646 /* Get the response header */
647 rsp
= (struct ncsi_rsp_oem_pkt
*)skb_network_header(nr
->rsp
);
648 mlx
= (struct ncsi_rsp_oem_mlx_pkt
*)(rsp
->data
);
650 if (mlx
->cmd
== NCSI_OEM_MLX_CMD_GMA
&&
651 mlx
->param
== NCSI_OEM_MLX_CMD_GMA_PARAM
)
652 return ncsi_rsp_handler_oem_mlx_gma(nr
);
656 /* Response handler for Broadcom command Get Mac Address */
657 static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request
*nr
)
659 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
660 struct net_device
*ndev
= ndp
->ndev
.dev
;
661 const struct net_device_ops
*ops
= ndev
->netdev_ops
;
662 struct ncsi_rsp_oem_pkt
*rsp
;
663 struct sockaddr saddr
;
666 /* Get the response header */
667 rsp
= (struct ncsi_rsp_oem_pkt
*)skb_network_header(nr
->rsp
);
669 saddr
.sa_family
= ndev
->type
;
670 ndev
->priv_flags
|= IFF_LIVE_ADDR_CHANGE
;
671 memcpy(saddr
.sa_data
, &rsp
->data
[BCM_MAC_ADDR_OFFSET
], ETH_ALEN
);
672 /* Increase mac address by 1 for BMC's address */
673 eth_addr_inc((u8
*)saddr
.sa_data
);
674 if (!is_valid_ether_addr((const u8
*)saddr
.sa_data
))
677 /* Set the flag for GMA command which should only be called once */
680 ret
= ops
->ndo_set_mac_address(ndev
, &saddr
);
682 netdev_warn(ndev
, "NCSI: 'Writing mac address to device failed\n");
687 /* Response handler for Broadcom card */
688 static int ncsi_rsp_handler_oem_bcm(struct ncsi_request
*nr
)
690 struct ncsi_rsp_oem_bcm_pkt
*bcm
;
691 struct ncsi_rsp_oem_pkt
*rsp
;
693 /* Get the response header */
694 rsp
= (struct ncsi_rsp_oem_pkt
*)skb_network_header(nr
->rsp
);
695 bcm
= (struct ncsi_rsp_oem_bcm_pkt
*)(rsp
->data
);
697 if (bcm
->type
== NCSI_OEM_BCM_CMD_GMA
)
698 return ncsi_rsp_handler_oem_bcm_gma(nr
);
702 static struct ncsi_rsp_oem_handler
{
704 int (*handler
)(struct ncsi_request
*nr
);
705 } ncsi_rsp_oem_handlers
[] = {
706 { NCSI_OEM_MFR_MLX_ID
, ncsi_rsp_handler_oem_mlx
},
707 { NCSI_OEM_MFR_BCM_ID
, ncsi_rsp_handler_oem_bcm
}
710 /* Response handler for OEM command */
711 static int ncsi_rsp_handler_oem(struct ncsi_request
*nr
)
713 struct ncsi_rsp_oem_handler
*nrh
= NULL
;
714 struct ncsi_rsp_oem_pkt
*rsp
;
715 unsigned int mfr_id
, i
;
717 /* Get the response header */
718 rsp
= (struct ncsi_rsp_oem_pkt
*)skb_network_header(nr
->rsp
);
719 mfr_id
= ntohl(rsp
->mfr_id
);
721 /* Check for manufacturer id and Find the handler */
722 for (i
= 0; i
< ARRAY_SIZE(ncsi_rsp_oem_handlers
); i
++) {
723 if (ncsi_rsp_oem_handlers
[i
].mfr_id
== mfr_id
) {
724 if (ncsi_rsp_oem_handlers
[i
].handler
)
725 nrh
= &ncsi_rsp_oem_handlers
[i
];
734 netdev_err(nr
->ndp
->ndev
.dev
, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
739 /* Process the packet */
740 return nrh
->handler(nr
);
743 static int ncsi_rsp_handler_gvi(struct ncsi_request
*nr
)
745 struct ncsi_rsp_gvi_pkt
*rsp
;
746 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
747 struct ncsi_channel
*nc
;
748 struct ncsi_channel_version
*ncv
;
751 /* Find the channel */
752 rsp
= (struct ncsi_rsp_gvi_pkt
*)skb_network_header(nr
->rsp
);
753 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
758 /* Update to channel's version info */
760 ncv
->version
= ntohl(rsp
->ncsi_version
);
761 ncv
->alpha2
= rsp
->alpha2
;
762 memcpy(ncv
->fw_name
, rsp
->fw_name
, 12);
763 ncv
->fw_version
= ntohl(rsp
->fw_version
);
764 for (i
= 0; i
< ARRAY_SIZE(ncv
->pci_ids
); i
++)
765 ncv
->pci_ids
[i
] = ntohs(rsp
->pci_ids
[i
]);
766 ncv
->mf_id
= ntohl(rsp
->mf_id
);
771 static int ncsi_rsp_handler_gc(struct ncsi_request
*nr
)
773 struct ncsi_rsp_gc_pkt
*rsp
;
774 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
775 struct ncsi_channel
*nc
;
778 /* Find the channel */
779 rsp
= (struct ncsi_rsp_gc_pkt
*)skb_network_header(nr
->rsp
);
780 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
785 /* Update channel's capabilities */
786 nc
->caps
[NCSI_CAP_GENERIC
].cap
= ntohl(rsp
->cap
) &
787 NCSI_CAP_GENERIC_MASK
;
788 nc
->caps
[NCSI_CAP_BC
].cap
= ntohl(rsp
->bc_cap
) &
790 nc
->caps
[NCSI_CAP_MC
].cap
= ntohl(rsp
->mc_cap
) &
792 nc
->caps
[NCSI_CAP_BUFFER
].cap
= ntohl(rsp
->buf_cap
);
793 nc
->caps
[NCSI_CAP_AEN
].cap
= ntohl(rsp
->aen_cap
) &
795 nc
->caps
[NCSI_CAP_VLAN
].cap
= rsp
->vlan_mode
&
798 size
= (rsp
->uc_cnt
+ rsp
->mc_cnt
+ rsp
->mixed_cnt
) * ETH_ALEN
;
799 nc
->mac_filter
.addrs
= kzalloc(size
, GFP_ATOMIC
);
800 if (!nc
->mac_filter
.addrs
)
802 nc
->mac_filter
.n_uc
= rsp
->uc_cnt
;
803 nc
->mac_filter
.n_mc
= rsp
->mc_cnt
;
804 nc
->mac_filter
.n_mixed
= rsp
->mixed_cnt
;
806 nc
->vlan_filter
.vids
= kcalloc(rsp
->vlan_cnt
,
807 sizeof(*nc
->vlan_filter
.vids
),
809 if (!nc
->vlan_filter
.vids
)
811 /* Set VLAN filters active so they are cleared in the first
812 * configuration state
814 nc
->vlan_filter
.bitmap
= U64_MAX
;
815 nc
->vlan_filter
.n_vids
= rsp
->vlan_cnt
;
820 static int ncsi_rsp_handler_gp(struct ncsi_request
*nr
)
822 struct ncsi_channel_vlan_filter
*ncvf
;
823 struct ncsi_channel_mac_filter
*ncmf
;
824 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
825 struct ncsi_rsp_gp_pkt
*rsp
;
826 struct ncsi_channel
*nc
;
827 unsigned short enable
;
828 unsigned char *pdata
;
833 /* Find the channel */
834 rsp
= (struct ncsi_rsp_gp_pkt
*)skb_network_header(nr
->rsp
);
835 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
840 /* Modes with explicit enabled indications */
841 if (ntohl(rsp
->valid_modes
) & 0x1) { /* BC filter mode */
842 nc
->modes
[NCSI_MODE_BC
].enable
= 1;
843 nc
->modes
[NCSI_MODE_BC
].data
[0] = ntohl(rsp
->bc_mode
);
845 if (ntohl(rsp
->valid_modes
) & 0x2) /* Channel enabled */
846 nc
->modes
[NCSI_MODE_ENABLE
].enable
= 1;
847 if (ntohl(rsp
->valid_modes
) & 0x4) /* Channel Tx enabled */
848 nc
->modes
[NCSI_MODE_TX_ENABLE
].enable
= 1;
849 if (ntohl(rsp
->valid_modes
) & 0x8) /* MC filter mode */
850 nc
->modes
[NCSI_MODE_MC
].enable
= 1;
852 /* Modes without explicit enabled indications */
853 nc
->modes
[NCSI_MODE_LINK
].enable
= 1;
854 nc
->modes
[NCSI_MODE_LINK
].data
[0] = ntohl(rsp
->link_mode
);
855 nc
->modes
[NCSI_MODE_VLAN
].enable
= 1;
856 nc
->modes
[NCSI_MODE_VLAN
].data
[0] = rsp
->vlan_mode
;
857 nc
->modes
[NCSI_MODE_FC
].enable
= 1;
858 nc
->modes
[NCSI_MODE_FC
].data
[0] = rsp
->fc_mode
;
859 nc
->modes
[NCSI_MODE_AEN
].enable
= 1;
860 nc
->modes
[NCSI_MODE_AEN
].data
[0] = ntohl(rsp
->aen_mode
);
862 /* MAC addresses filter table */
863 pdata
= (unsigned char *)rsp
+ 48;
864 enable
= rsp
->mac_enable
;
865 ncmf
= &nc
->mac_filter
;
866 spin_lock_irqsave(&nc
->lock
, flags
);
867 bitmap
= &ncmf
->bitmap
;
868 for (i
= 0; i
< rsp
->mac_cnt
; i
++, pdata
+= 6) {
869 if (!(enable
& (0x1 << i
)))
870 clear_bit(i
, bitmap
);
874 memcpy(&ncmf
->addrs
[i
* ETH_ALEN
], pdata
, ETH_ALEN
);
876 spin_unlock_irqrestore(&nc
->lock
, flags
);
878 /* VLAN filter table */
879 enable
= ntohs(rsp
->vlan_enable
);
880 ncvf
= &nc
->vlan_filter
;
881 bitmap
= &ncvf
->bitmap
;
882 spin_lock_irqsave(&nc
->lock
, flags
);
883 for (i
= 0; i
< rsp
->vlan_cnt
; i
++, pdata
+= 2) {
884 if (!(enable
& (0x1 << i
)))
885 clear_bit(i
, bitmap
);
889 ncvf
->vids
[i
] = ntohs(*(__be16
*)pdata
);
891 spin_unlock_irqrestore(&nc
->lock
, flags
);
896 static int ncsi_rsp_handler_gcps(struct ncsi_request
*nr
)
898 struct ncsi_rsp_gcps_pkt
*rsp
;
899 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
900 struct ncsi_channel
*nc
;
901 struct ncsi_channel_stats
*ncs
;
903 /* Find the channel */
904 rsp
= (struct ncsi_rsp_gcps_pkt
*)skb_network_header(nr
->rsp
);
905 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
910 /* Update HNC's statistics */
912 ncs
->hnc_cnt_hi
= ntohl(rsp
->cnt_hi
);
913 ncs
->hnc_cnt_lo
= ntohl(rsp
->cnt_lo
);
914 ncs
->hnc_rx_bytes
= ntohl(rsp
->rx_bytes
);
915 ncs
->hnc_tx_bytes
= ntohl(rsp
->tx_bytes
);
916 ncs
->hnc_rx_uc_pkts
= ntohl(rsp
->rx_uc_pkts
);
917 ncs
->hnc_rx_mc_pkts
= ntohl(rsp
->rx_mc_pkts
);
918 ncs
->hnc_rx_bc_pkts
= ntohl(rsp
->rx_bc_pkts
);
919 ncs
->hnc_tx_uc_pkts
= ntohl(rsp
->tx_uc_pkts
);
920 ncs
->hnc_tx_mc_pkts
= ntohl(rsp
->tx_mc_pkts
);
921 ncs
->hnc_tx_bc_pkts
= ntohl(rsp
->tx_bc_pkts
);
922 ncs
->hnc_fcs_err
= ntohl(rsp
->fcs_err
);
923 ncs
->hnc_align_err
= ntohl(rsp
->align_err
);
924 ncs
->hnc_false_carrier
= ntohl(rsp
->false_carrier
);
925 ncs
->hnc_runt_pkts
= ntohl(rsp
->runt_pkts
);
926 ncs
->hnc_jabber_pkts
= ntohl(rsp
->jabber_pkts
);
927 ncs
->hnc_rx_pause_xon
= ntohl(rsp
->rx_pause_xon
);
928 ncs
->hnc_rx_pause_xoff
= ntohl(rsp
->rx_pause_xoff
);
929 ncs
->hnc_tx_pause_xon
= ntohl(rsp
->tx_pause_xon
);
930 ncs
->hnc_tx_pause_xoff
= ntohl(rsp
->tx_pause_xoff
);
931 ncs
->hnc_tx_s_collision
= ntohl(rsp
->tx_s_collision
);
932 ncs
->hnc_tx_m_collision
= ntohl(rsp
->tx_m_collision
);
933 ncs
->hnc_l_collision
= ntohl(rsp
->l_collision
);
934 ncs
->hnc_e_collision
= ntohl(rsp
->e_collision
);
935 ncs
->hnc_rx_ctl_frames
= ntohl(rsp
->rx_ctl_frames
);
936 ncs
->hnc_rx_64_frames
= ntohl(rsp
->rx_64_frames
);
937 ncs
->hnc_rx_127_frames
= ntohl(rsp
->rx_127_frames
);
938 ncs
->hnc_rx_255_frames
= ntohl(rsp
->rx_255_frames
);
939 ncs
->hnc_rx_511_frames
= ntohl(rsp
->rx_511_frames
);
940 ncs
->hnc_rx_1023_frames
= ntohl(rsp
->rx_1023_frames
);
941 ncs
->hnc_rx_1522_frames
= ntohl(rsp
->rx_1522_frames
);
942 ncs
->hnc_rx_9022_frames
= ntohl(rsp
->rx_9022_frames
);
943 ncs
->hnc_tx_64_frames
= ntohl(rsp
->tx_64_frames
);
944 ncs
->hnc_tx_127_frames
= ntohl(rsp
->tx_127_frames
);
945 ncs
->hnc_tx_255_frames
= ntohl(rsp
->tx_255_frames
);
946 ncs
->hnc_tx_511_frames
= ntohl(rsp
->tx_511_frames
);
947 ncs
->hnc_tx_1023_frames
= ntohl(rsp
->tx_1023_frames
);
948 ncs
->hnc_tx_1522_frames
= ntohl(rsp
->tx_1522_frames
);
949 ncs
->hnc_tx_9022_frames
= ntohl(rsp
->tx_9022_frames
);
950 ncs
->hnc_rx_valid_bytes
= ntohl(rsp
->rx_valid_bytes
);
951 ncs
->hnc_rx_runt_pkts
= ntohl(rsp
->rx_runt_pkts
);
952 ncs
->hnc_rx_jabber_pkts
= ntohl(rsp
->rx_jabber_pkts
);
957 static int ncsi_rsp_handler_gns(struct ncsi_request
*nr
)
959 struct ncsi_rsp_gns_pkt
*rsp
;
960 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
961 struct ncsi_channel
*nc
;
962 struct ncsi_channel_stats
*ncs
;
964 /* Find the channel */
965 rsp
= (struct ncsi_rsp_gns_pkt
*)skb_network_header(nr
->rsp
);
966 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
971 /* Update HNC's statistics */
973 ncs
->ncsi_rx_cmds
= ntohl(rsp
->rx_cmds
);
974 ncs
->ncsi_dropped_cmds
= ntohl(rsp
->dropped_cmds
);
975 ncs
->ncsi_cmd_type_errs
= ntohl(rsp
->cmd_type_errs
);
976 ncs
->ncsi_cmd_csum_errs
= ntohl(rsp
->cmd_csum_errs
);
977 ncs
->ncsi_rx_pkts
= ntohl(rsp
->rx_pkts
);
978 ncs
->ncsi_tx_pkts
= ntohl(rsp
->tx_pkts
);
979 ncs
->ncsi_tx_aen_pkts
= ntohl(rsp
->tx_aen_pkts
);
984 static int ncsi_rsp_handler_gnpts(struct ncsi_request
*nr
)
986 struct ncsi_rsp_gnpts_pkt
*rsp
;
987 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
988 struct ncsi_channel
*nc
;
989 struct ncsi_channel_stats
*ncs
;
991 /* Find the channel */
992 rsp
= (struct ncsi_rsp_gnpts_pkt
*)skb_network_header(nr
->rsp
);
993 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
998 /* Update HNC's statistics */
1000 ncs
->pt_tx_pkts
= ntohl(rsp
->tx_pkts
);
1001 ncs
->pt_tx_dropped
= ntohl(rsp
->tx_dropped
);
1002 ncs
->pt_tx_channel_err
= ntohl(rsp
->tx_channel_err
);
1003 ncs
->pt_tx_us_err
= ntohl(rsp
->tx_us_err
);
1004 ncs
->pt_rx_pkts
= ntohl(rsp
->rx_pkts
);
1005 ncs
->pt_rx_dropped
= ntohl(rsp
->rx_dropped
);
1006 ncs
->pt_rx_channel_err
= ntohl(rsp
->rx_channel_err
);
1007 ncs
->pt_rx_us_err
= ntohl(rsp
->rx_us_err
);
1008 ncs
->pt_rx_os_err
= ntohl(rsp
->rx_os_err
);
1013 static int ncsi_rsp_handler_gps(struct ncsi_request
*nr
)
1015 struct ncsi_rsp_gps_pkt
*rsp
;
1016 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
1017 struct ncsi_package
*np
;
1019 /* Find the package */
1020 rsp
= (struct ncsi_rsp_gps_pkt
*)skb_network_header(nr
->rsp
);
1021 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
1029 static int ncsi_rsp_handler_gpuuid(struct ncsi_request
*nr
)
1031 struct ncsi_rsp_gpuuid_pkt
*rsp
;
1032 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
1033 struct ncsi_package
*np
;
1035 /* Find the package */
1036 rsp
= (struct ncsi_rsp_gpuuid_pkt
*)skb_network_header(nr
->rsp
);
1037 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
1042 memcpy(np
->uuid
, rsp
->uuid
, sizeof(rsp
->uuid
));
1047 static int ncsi_rsp_handler_pldm(struct ncsi_request
*nr
)
1052 static int ncsi_rsp_handler_netlink(struct ncsi_request
*nr
)
1054 struct ncsi_dev_priv
*ndp
= nr
->ndp
;
1055 struct ncsi_rsp_pkt
*rsp
;
1056 struct ncsi_package
*np
;
1057 struct ncsi_channel
*nc
;
1060 /* Find the package */
1061 rsp
= (struct ncsi_rsp_pkt
*)skb_network_header(nr
->rsp
);
1062 ncsi_find_package_and_channel(ndp
, rsp
->rsp
.common
.channel
,
1067 ret
= ncsi_send_netlink_rsp(nr
, np
, nc
);
1072 static struct ncsi_rsp_handler
{
1075 int (*handler
)(struct ncsi_request
*nr
);
1076 } ncsi_rsp_handlers
[] = {
1077 { NCSI_PKT_RSP_CIS
, 4, ncsi_rsp_handler_cis
},
1078 { NCSI_PKT_RSP_SP
, 4, ncsi_rsp_handler_sp
},
1079 { NCSI_PKT_RSP_DP
, 4, ncsi_rsp_handler_dp
},
1080 { NCSI_PKT_RSP_EC
, 4, ncsi_rsp_handler_ec
},
1081 { NCSI_PKT_RSP_DC
, 4, ncsi_rsp_handler_dc
},
1082 { NCSI_PKT_RSP_RC
, 4, ncsi_rsp_handler_rc
},
1083 { NCSI_PKT_RSP_ECNT
, 4, ncsi_rsp_handler_ecnt
},
1084 { NCSI_PKT_RSP_DCNT
, 4, ncsi_rsp_handler_dcnt
},
1085 { NCSI_PKT_RSP_AE
, 4, ncsi_rsp_handler_ae
},
1086 { NCSI_PKT_RSP_SL
, 4, ncsi_rsp_handler_sl
},
1087 { NCSI_PKT_RSP_GLS
, 16, ncsi_rsp_handler_gls
},
1088 { NCSI_PKT_RSP_SVF
, 4, ncsi_rsp_handler_svf
},
1089 { NCSI_PKT_RSP_EV
, 4, ncsi_rsp_handler_ev
},
1090 { NCSI_PKT_RSP_DV
, 4, ncsi_rsp_handler_dv
},
1091 { NCSI_PKT_RSP_SMA
, 4, ncsi_rsp_handler_sma
},
1092 { NCSI_PKT_RSP_EBF
, 4, ncsi_rsp_handler_ebf
},
1093 { NCSI_PKT_RSP_DBF
, 4, ncsi_rsp_handler_dbf
},
1094 { NCSI_PKT_RSP_EGMF
, 4, ncsi_rsp_handler_egmf
},
1095 { NCSI_PKT_RSP_DGMF
, 4, ncsi_rsp_handler_dgmf
},
1096 { NCSI_PKT_RSP_SNFC
, 4, ncsi_rsp_handler_snfc
},
1097 { NCSI_PKT_RSP_GVI
, 40, ncsi_rsp_handler_gvi
},
1098 { NCSI_PKT_RSP_GC
, 32, ncsi_rsp_handler_gc
},
1099 { NCSI_PKT_RSP_GP
, -1, ncsi_rsp_handler_gp
},
1100 { NCSI_PKT_RSP_GCPS
, 204, ncsi_rsp_handler_gcps
},
1101 { NCSI_PKT_RSP_GNS
, 32, ncsi_rsp_handler_gns
},
1102 { NCSI_PKT_RSP_GNPTS
, 48, ncsi_rsp_handler_gnpts
},
1103 { NCSI_PKT_RSP_GPS
, 8, ncsi_rsp_handler_gps
},
1104 { NCSI_PKT_RSP_OEM
, -1, ncsi_rsp_handler_oem
},
1105 { NCSI_PKT_RSP_PLDM
, -1, ncsi_rsp_handler_pldm
},
1106 { NCSI_PKT_RSP_GPUUID
, 20, ncsi_rsp_handler_gpuuid
},
1107 { NCSI_PKT_RSP_QPNPR
, -1, ncsi_rsp_handler_pldm
},
1108 { NCSI_PKT_RSP_SNPR
, -1, ncsi_rsp_handler_pldm
}
1111 int ncsi_rcv_rsp(struct sk_buff
*skb
, struct net_device
*dev
,
1112 struct packet_type
*pt
, struct net_device
*orig_dev
)
1114 struct ncsi_rsp_handler
*nrh
= NULL
;
1115 struct ncsi_dev
*nd
;
1116 struct ncsi_dev_priv
*ndp
;
1117 struct ncsi_request
*nr
;
1118 struct ncsi_pkt_hdr
*hdr
;
1119 unsigned long flags
;
1120 int payload
, i
, ret
;
1122 /* Find the NCSI device */
1123 nd
= ncsi_find_dev(orig_dev
);
1124 ndp
= nd
? TO_NCSI_DEV_PRIV(nd
) : NULL
;
1128 /* Check if it is AEN packet */
1129 hdr
= (struct ncsi_pkt_hdr
*)skb_network_header(skb
);
1130 if (hdr
->type
== NCSI_PKT_AEN
)
1131 return ncsi_aen_handler(ndp
, skb
);
1133 /* Find the handler */
1134 for (i
= 0; i
< ARRAY_SIZE(ncsi_rsp_handlers
); i
++) {
1135 if (ncsi_rsp_handlers
[i
].type
== hdr
->type
) {
1136 if (ncsi_rsp_handlers
[i
].handler
)
1137 nrh
= &ncsi_rsp_handlers
[i
];
1146 netdev_err(nd
->dev
, "Received unrecognized packet (0x%x)\n",
1151 /* Associate with the request */
1152 spin_lock_irqsave(&ndp
->lock
, flags
);
1153 nr
= &ndp
->requests
[hdr
->id
];
1155 spin_unlock_irqrestore(&ndp
->lock
, flags
);
1161 spin_unlock_irqrestore(&ndp
->lock
, flags
);
1166 /* Validate the packet */
1167 spin_unlock_irqrestore(&ndp
->lock
, flags
);
1168 payload
= nrh
->payload
;
1170 payload
= ntohs(hdr
->length
);
1171 ret
= ncsi_validate_rsp_pkt(nr
, payload
);
1173 netdev_warn(ndp
->ndev
.dev
,
1174 "NCSI: 'bad' packet ignored for type 0x%x\n",
1177 if (nr
->flags
== NCSI_REQ_FLAG_NETLINK_DRIVEN
) {
1181 ncsi_send_netlink_err(ndp
->ndev
.dev
,
1190 /* Process the packet */
1191 ret
= nrh
->handler(nr
);
1193 netdev_err(ndp
->ndev
.dev
,
1194 "NCSI: Handler for packet type 0x%x returned %d\n",
1198 if (nr
->flags
== NCSI_REQ_FLAG_NETLINK_DRIVEN
) {
1199 ret
= ncsi_rsp_handler_netlink(nr
);
1201 netdev_err(ndp
->ndev
.dev
,
1202 "NCSI: Netlink handler for packet type 0x%x returned %d\n",
1208 ncsi_free_request(nr
);