0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/kernel.h>
0008 #include <linux/init.h>
0009 #include <linux/netdevice.h>
0010 #include <linux/etherdevice.h>
0011 #include <linux/skbuff.h>
0012
0013 #include <net/ncsi.h>
0014 #include <net/net_namespace.h>
0015 #include <net/sock.h>
0016 #include <net/genetlink.h>
0017
0018 #include "internal.h"
0019 #include "ncsi-pkt.h"
0020 #include "ncsi-netlink.h"
0021
0022 static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
0023 unsigned short payload)
0024 {
0025 struct ncsi_rsp_pkt_hdr *h;
0026 u32 checksum;
0027 __be32 *pchecksum;
0028
0029
0030
0031
0032
0033 h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);
0034
0035 if (h->common.revision != NCSI_PKT_REVISION) {
0036 netdev_dbg(nr->ndp->ndev.dev,
0037 "NCSI: unsupported header revision\n");
0038 return -EINVAL;
0039 }
0040 if (ntohs(h->common.length) != payload) {
0041 netdev_dbg(nr->ndp->ndev.dev,
0042 "NCSI: payload length mismatched\n");
0043 return -EINVAL;
0044 }
0045
0046
0047 if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED ||
0048 ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) {
0049 netdev_dbg(nr->ndp->ndev.dev,
0050 "NCSI: non zero response/reason code %04xh, %04xh\n",
0051 ntohs(h->code), ntohs(h->reason));
0052 return -EPERM;
0053 }
0054
0055
0056
0057
0058
0059 pchecksum = (__be32 *)((void *)(h + 1) + ALIGN(payload, 4) - 4);
0060 if (ntohl(*pchecksum) == 0)
0061 return 0;
0062
0063 checksum = ncsi_calculate_checksum((unsigned char *)h,
0064 sizeof(*h) + payload - 4);
0065
0066 if (*pchecksum != htonl(checksum)) {
0067 netdev_dbg(nr->ndp->ndev.dev,
0068 "NCSI: checksum mismatched; recd: %08x calc: %08x\n",
0069 *pchecksum, htonl(checksum));
0070 return -EINVAL;
0071 }
0072
0073 return 0;
0074 }
0075
0076 static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
0077 {
0078 struct ncsi_rsp_pkt *rsp;
0079 struct ncsi_dev_priv *ndp = nr->ndp;
0080 struct ncsi_package *np;
0081 struct ncsi_channel *nc;
0082 unsigned char id;
0083
0084 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0085 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, &np, &nc);
0086 if (!nc) {
0087 if (ndp->flags & NCSI_DEV_PROBED)
0088 return -ENXIO;
0089
0090 id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
0091 nc = ncsi_add_channel(np, id);
0092 }
0093
0094 return nc ? 0 : -ENODEV;
0095 }
0096
0097 static int ncsi_rsp_handler_sp(struct ncsi_request *nr)
0098 {
0099 struct ncsi_rsp_pkt *rsp;
0100 struct ncsi_dev_priv *ndp = nr->ndp;
0101 struct ncsi_package *np;
0102 unsigned char id;
0103
0104
0105
0106
0107 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0108 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0109 &np, NULL);
0110 if (!np) {
0111 if (ndp->flags & NCSI_DEV_PROBED)
0112 return -ENXIO;
0113
0114 id = NCSI_PACKAGE_INDEX(rsp->rsp.common.channel);
0115 np = ncsi_add_package(ndp, id);
0116 if (!np)
0117 return -ENODEV;
0118 }
0119
0120 return 0;
0121 }
0122
0123 static int ncsi_rsp_handler_dp(struct ncsi_request *nr)
0124 {
0125 struct ncsi_rsp_pkt *rsp;
0126 struct ncsi_dev_priv *ndp = nr->ndp;
0127 struct ncsi_package *np;
0128 struct ncsi_channel *nc;
0129 unsigned long flags;
0130
0131
0132 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0133 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0134 &np, NULL);
0135 if (!np)
0136 return -ENODEV;
0137
0138
0139 NCSI_FOR_EACH_CHANNEL(np, nc) {
0140 spin_lock_irqsave(&nc->lock, flags);
0141 nc->state = NCSI_CHANNEL_INACTIVE;
0142 spin_unlock_irqrestore(&nc->lock, flags);
0143 }
0144
0145 return 0;
0146 }
0147
0148 static int ncsi_rsp_handler_ec(struct ncsi_request *nr)
0149 {
0150 struct ncsi_rsp_pkt *rsp;
0151 struct ncsi_dev_priv *ndp = nr->ndp;
0152 struct ncsi_channel *nc;
0153 struct ncsi_channel_mode *ncm;
0154
0155
0156 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0157 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0158 NULL, &nc);
0159 if (!nc)
0160 return -ENODEV;
0161
0162 ncm = &nc->modes[NCSI_MODE_ENABLE];
0163 if (ncm->enable)
0164 return 0;
0165
0166 ncm->enable = 1;
0167 return 0;
0168 }
0169
0170 static int ncsi_rsp_handler_dc(struct ncsi_request *nr)
0171 {
0172 struct ncsi_rsp_pkt *rsp;
0173 struct ncsi_dev_priv *ndp = nr->ndp;
0174 struct ncsi_channel *nc;
0175 struct ncsi_channel_mode *ncm;
0176 int ret;
0177
0178 ret = ncsi_validate_rsp_pkt(nr, 4);
0179 if (ret)
0180 return ret;
0181
0182
0183 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0184 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0185 NULL, &nc);
0186 if (!nc)
0187 return -ENODEV;
0188
0189 ncm = &nc->modes[NCSI_MODE_ENABLE];
0190 if (!ncm->enable)
0191 return 0;
0192
0193 ncm->enable = 0;
0194 return 0;
0195 }
0196
0197 static int ncsi_rsp_handler_rc(struct ncsi_request *nr)
0198 {
0199 struct ncsi_rsp_pkt *rsp;
0200 struct ncsi_dev_priv *ndp = nr->ndp;
0201 struct ncsi_channel *nc;
0202 unsigned long flags;
0203
0204
0205 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0206 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0207 NULL, &nc);
0208 if (!nc)
0209 return -ENODEV;
0210
0211
0212 spin_lock_irqsave(&nc->lock, flags);
0213 nc->state = NCSI_CHANNEL_INACTIVE;
0214 spin_unlock_irqrestore(&nc->lock, flags);
0215
0216 return 0;
0217 }
0218
0219 static int ncsi_rsp_handler_ecnt(struct ncsi_request *nr)
0220 {
0221 struct ncsi_rsp_pkt *rsp;
0222 struct ncsi_dev_priv *ndp = nr->ndp;
0223 struct ncsi_channel *nc;
0224 struct ncsi_channel_mode *ncm;
0225
0226
0227 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0228 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0229 NULL, &nc);
0230 if (!nc)
0231 return -ENODEV;
0232
0233 ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
0234 if (ncm->enable)
0235 return 0;
0236
0237 ncm->enable = 1;
0238 return 0;
0239 }
0240
0241 static int ncsi_rsp_handler_dcnt(struct ncsi_request *nr)
0242 {
0243 struct ncsi_rsp_pkt *rsp;
0244 struct ncsi_dev_priv *ndp = nr->ndp;
0245 struct ncsi_channel *nc;
0246 struct ncsi_channel_mode *ncm;
0247
0248
0249 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0250 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0251 NULL, &nc);
0252 if (!nc)
0253 return -ENODEV;
0254
0255 ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
0256 if (!ncm->enable)
0257 return 0;
0258
0259 ncm->enable = 0;
0260 return 0;
0261 }
0262
0263 static int ncsi_rsp_handler_ae(struct ncsi_request *nr)
0264 {
0265 struct ncsi_cmd_ae_pkt *cmd;
0266 struct ncsi_rsp_pkt *rsp;
0267 struct ncsi_dev_priv *ndp = nr->ndp;
0268 struct ncsi_channel *nc;
0269 struct ncsi_channel_mode *ncm;
0270
0271
0272 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0273 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0274 NULL, &nc);
0275 if (!nc)
0276 return -ENODEV;
0277
0278
0279 ncm = &nc->modes[NCSI_MODE_AEN];
0280 if (ncm->enable)
0281 return 0;
0282
0283
0284 cmd = (struct ncsi_cmd_ae_pkt *)skb_network_header(nr->cmd);
0285 ncm->enable = 1;
0286 ncm->data[0] = cmd->mc_id;
0287 ncm->data[1] = ntohl(cmd->mode);
0288
0289 return 0;
0290 }
0291
0292 static int ncsi_rsp_handler_sl(struct ncsi_request *nr)
0293 {
0294 struct ncsi_cmd_sl_pkt *cmd;
0295 struct ncsi_rsp_pkt *rsp;
0296 struct ncsi_dev_priv *ndp = nr->ndp;
0297 struct ncsi_channel *nc;
0298 struct ncsi_channel_mode *ncm;
0299
0300
0301 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0302 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0303 NULL, &nc);
0304 if (!nc)
0305 return -ENODEV;
0306
0307 cmd = (struct ncsi_cmd_sl_pkt *)skb_network_header(nr->cmd);
0308 ncm = &nc->modes[NCSI_MODE_LINK];
0309 ncm->data[0] = ntohl(cmd->mode);
0310 ncm->data[1] = ntohl(cmd->oem_mode);
0311
0312 return 0;
0313 }
0314
0315 static int ncsi_rsp_handler_gls(struct ncsi_request *nr)
0316 {
0317 struct ncsi_rsp_gls_pkt *rsp;
0318 struct ncsi_dev_priv *ndp = nr->ndp;
0319 struct ncsi_channel *nc;
0320 struct ncsi_channel_mode *ncm;
0321 unsigned long flags;
0322
0323
0324 rsp = (struct ncsi_rsp_gls_pkt *)skb_network_header(nr->rsp);
0325 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0326 NULL, &nc);
0327 if (!nc)
0328 return -ENODEV;
0329
0330 ncm = &nc->modes[NCSI_MODE_LINK];
0331 ncm->data[2] = ntohl(rsp->status);
0332 ncm->data[3] = ntohl(rsp->other);
0333 ncm->data[4] = ntohl(rsp->oem_status);
0334
0335 if (nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN)
0336 return 0;
0337
0338
0339 spin_lock_irqsave(&nc->lock, flags);
0340 nc->monitor.state = NCSI_CHANNEL_MONITOR_START;
0341 spin_unlock_irqrestore(&nc->lock, flags);
0342
0343 return 0;
0344 }
0345
0346 static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
0347 {
0348 struct ncsi_cmd_svf_pkt *cmd;
0349 struct ncsi_rsp_pkt *rsp;
0350 struct ncsi_dev_priv *ndp = nr->ndp;
0351 struct ncsi_channel *nc;
0352 struct ncsi_channel_vlan_filter *ncf;
0353 unsigned long flags;
0354 void *bitmap;
0355
0356
0357 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0358 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0359 NULL, &nc);
0360 if (!nc)
0361 return -ENODEV;
0362
0363 cmd = (struct ncsi_cmd_svf_pkt *)skb_network_header(nr->cmd);
0364 ncf = &nc->vlan_filter;
0365 if (cmd->index == 0 || cmd->index > ncf->n_vids)
0366 return -ERANGE;
0367
0368
0369 spin_lock_irqsave(&nc->lock, flags);
0370 bitmap = &ncf->bitmap;
0371 if (!(cmd->enable & 0x1)) {
0372 if (test_and_clear_bit(cmd->index - 1, bitmap))
0373 ncf->vids[cmd->index - 1] = 0;
0374 } else {
0375 set_bit(cmd->index - 1, bitmap);
0376 ncf->vids[cmd->index - 1] = ntohs(cmd->vlan);
0377 }
0378 spin_unlock_irqrestore(&nc->lock, flags);
0379
0380 return 0;
0381 }
0382
0383 static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
0384 {
0385 struct ncsi_cmd_ev_pkt *cmd;
0386 struct ncsi_rsp_pkt *rsp;
0387 struct ncsi_dev_priv *ndp = nr->ndp;
0388 struct ncsi_channel *nc;
0389 struct ncsi_channel_mode *ncm;
0390
0391
0392 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0393 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0394 NULL, &nc);
0395 if (!nc)
0396 return -ENODEV;
0397
0398
0399 ncm = &nc->modes[NCSI_MODE_VLAN];
0400 if (ncm->enable)
0401 return 0;
0402
0403
0404 cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
0405 ncm->enable = 1;
0406 ncm->data[0] = ntohl((__force __be32)cmd->mode);
0407
0408 return 0;
0409 }
0410
0411 static int ncsi_rsp_handler_dv(struct ncsi_request *nr)
0412 {
0413 struct ncsi_rsp_pkt *rsp;
0414 struct ncsi_dev_priv *ndp = nr->ndp;
0415 struct ncsi_channel *nc;
0416 struct ncsi_channel_mode *ncm;
0417
0418
0419 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0420 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0421 NULL, &nc);
0422 if (!nc)
0423 return -ENODEV;
0424
0425
0426 ncm = &nc->modes[NCSI_MODE_VLAN];
0427 if (!ncm->enable)
0428 return 0;
0429
0430
0431 ncm->enable = 0;
0432 return 0;
0433 }
0434
0435 static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
0436 {
0437 struct ncsi_cmd_sma_pkt *cmd;
0438 struct ncsi_rsp_pkt *rsp;
0439 struct ncsi_dev_priv *ndp = nr->ndp;
0440 struct ncsi_channel *nc;
0441 struct ncsi_channel_mac_filter *ncf;
0442 unsigned long flags;
0443 void *bitmap;
0444 bool enabled;
0445 int index;
0446
0447
0448
0449 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0450 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0451 NULL, &nc);
0452 if (!nc)
0453 return -ENODEV;
0454
0455
0456
0457
0458 cmd = (struct ncsi_cmd_sma_pkt *)skb_network_header(nr->cmd);
0459 enabled = cmd->at_e & 0x1;
0460 ncf = &nc->mac_filter;
0461 bitmap = &ncf->bitmap;
0462
0463 if (cmd->index == 0 ||
0464 cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
0465 return -ERANGE;
0466
0467 index = (cmd->index - 1) * ETH_ALEN;
0468 spin_lock_irqsave(&nc->lock, flags);
0469 if (enabled) {
0470 set_bit(cmd->index - 1, bitmap);
0471 memcpy(&ncf->addrs[index], cmd->mac, ETH_ALEN);
0472 } else {
0473 clear_bit(cmd->index - 1, bitmap);
0474 eth_zero_addr(&ncf->addrs[index]);
0475 }
0476 spin_unlock_irqrestore(&nc->lock, flags);
0477
0478 return 0;
0479 }
0480
0481 static int ncsi_rsp_handler_ebf(struct ncsi_request *nr)
0482 {
0483 struct ncsi_cmd_ebf_pkt *cmd;
0484 struct ncsi_rsp_pkt *rsp;
0485 struct ncsi_dev_priv *ndp = nr->ndp;
0486 struct ncsi_channel *nc;
0487 struct ncsi_channel_mode *ncm;
0488
0489
0490 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0491 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, NULL, &nc);
0492 if (!nc)
0493 return -ENODEV;
0494
0495
0496 ncm = &nc->modes[NCSI_MODE_BC];
0497 if (ncm->enable)
0498 return 0;
0499
0500
0501 cmd = (struct ncsi_cmd_ebf_pkt *)skb_network_header(nr->cmd);
0502 ncm->enable = 1;
0503 ncm->data[0] = ntohl(cmd->mode);
0504
0505 return 0;
0506 }
0507
0508 static int ncsi_rsp_handler_dbf(struct ncsi_request *nr)
0509 {
0510 struct ncsi_rsp_pkt *rsp;
0511 struct ncsi_dev_priv *ndp = nr->ndp;
0512 struct ncsi_channel *nc;
0513 struct ncsi_channel_mode *ncm;
0514
0515 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0516 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0517 NULL, &nc);
0518 if (!nc)
0519 return -ENODEV;
0520
0521
0522 ncm = &nc->modes[NCSI_MODE_BC];
0523 if (!ncm->enable)
0524 return 0;
0525
0526
0527 ncm->enable = 0;
0528 ncm->data[0] = 0;
0529
0530 return 0;
0531 }
0532
0533 static int ncsi_rsp_handler_egmf(struct ncsi_request *nr)
0534 {
0535 struct ncsi_cmd_egmf_pkt *cmd;
0536 struct ncsi_rsp_pkt *rsp;
0537 struct ncsi_dev_priv *ndp = nr->ndp;
0538 struct ncsi_channel *nc;
0539 struct ncsi_channel_mode *ncm;
0540
0541
0542 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0543 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0544 NULL, &nc);
0545 if (!nc)
0546 return -ENODEV;
0547
0548
0549 ncm = &nc->modes[NCSI_MODE_MC];
0550 if (ncm->enable)
0551 return 0;
0552
0553
0554 cmd = (struct ncsi_cmd_egmf_pkt *)skb_network_header(nr->cmd);
0555 ncm->enable = 1;
0556 ncm->data[0] = ntohl(cmd->mode);
0557
0558 return 0;
0559 }
0560
0561 static int ncsi_rsp_handler_dgmf(struct ncsi_request *nr)
0562 {
0563 struct ncsi_rsp_pkt *rsp;
0564 struct ncsi_dev_priv *ndp = nr->ndp;
0565 struct ncsi_channel *nc;
0566 struct ncsi_channel_mode *ncm;
0567
0568 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0569 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0570 NULL, &nc);
0571 if (!nc)
0572 return -ENODEV;
0573
0574
0575 ncm = &nc->modes[NCSI_MODE_MC];
0576 if (!ncm->enable)
0577 return 0;
0578
0579
0580 ncm->enable = 0;
0581 ncm->data[0] = 0;
0582
0583 return 0;
0584 }
0585
0586 static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
0587 {
0588 struct ncsi_cmd_snfc_pkt *cmd;
0589 struct ncsi_rsp_pkt *rsp;
0590 struct ncsi_dev_priv *ndp = nr->ndp;
0591 struct ncsi_channel *nc;
0592 struct ncsi_channel_mode *ncm;
0593
0594
0595 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
0596 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0597 NULL, &nc);
0598 if (!nc)
0599 return -ENODEV;
0600
0601
0602 ncm = &nc->modes[NCSI_MODE_FC];
0603 if (ncm->enable)
0604 return 0;
0605
0606
0607 cmd = (struct ncsi_cmd_snfc_pkt *)skb_network_header(nr->cmd);
0608 ncm->enable = 1;
0609 ncm->data[0] = cmd->mode;
0610
0611 return 0;
0612 }
0613
0614
0615 static int ncsi_rsp_handler_oem_mlx_gma(struct ncsi_request *nr)
0616 {
0617 struct ncsi_dev_priv *ndp = nr->ndp;
0618 struct net_device *ndev = ndp->ndev.dev;
0619 const struct net_device_ops *ops = ndev->netdev_ops;
0620 struct ncsi_rsp_oem_pkt *rsp;
0621 struct sockaddr saddr;
0622 int ret = 0;
0623
0624
0625 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0626
0627 saddr.sa_family = ndev->type;
0628 ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
0629 memcpy(saddr.sa_data, &rsp->data[MLX_MAC_ADDR_OFFSET], ETH_ALEN);
0630
0631 ndp->gma_flag = 1;
0632
0633 ret = ops->ndo_set_mac_address(ndev, &saddr);
0634 if (ret < 0)
0635 netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
0636
0637 return ret;
0638 }
0639
0640
0641 static int ncsi_rsp_handler_oem_mlx(struct ncsi_request *nr)
0642 {
0643 struct ncsi_rsp_oem_mlx_pkt *mlx;
0644 struct ncsi_rsp_oem_pkt *rsp;
0645
0646
0647 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0648 mlx = (struct ncsi_rsp_oem_mlx_pkt *)(rsp->data);
0649
0650 if (mlx->cmd == NCSI_OEM_MLX_CMD_GMA &&
0651 mlx->param == NCSI_OEM_MLX_CMD_GMA_PARAM)
0652 return ncsi_rsp_handler_oem_mlx_gma(nr);
0653 return 0;
0654 }
0655
0656
0657 static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
0658 {
0659 struct ncsi_dev_priv *ndp = nr->ndp;
0660 struct net_device *ndev = ndp->ndev.dev;
0661 const struct net_device_ops *ops = ndev->netdev_ops;
0662 struct ncsi_rsp_oem_pkt *rsp;
0663 struct sockaddr saddr;
0664 int ret = 0;
0665
0666
0667 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0668
0669 saddr.sa_family = ndev->type;
0670 ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
0671 memcpy(saddr.sa_data, &rsp->data[BCM_MAC_ADDR_OFFSET], ETH_ALEN);
0672
0673 eth_addr_inc((u8 *)saddr.sa_data);
0674 if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
0675 return -ENXIO;
0676
0677
0678 ndp->gma_flag = 1;
0679
0680 ret = ops->ndo_set_mac_address(ndev, &saddr);
0681 if (ret < 0)
0682 netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
0683
0684 return ret;
0685 }
0686
0687
0688 static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
0689 {
0690 struct ncsi_rsp_oem_bcm_pkt *bcm;
0691 struct ncsi_rsp_oem_pkt *rsp;
0692
0693
0694 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0695 bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
0696
0697 if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
0698 return ncsi_rsp_handler_oem_bcm_gma(nr);
0699 return 0;
0700 }
0701
0702
0703 static int ncsi_rsp_handler_oem_intel_gma(struct ncsi_request *nr)
0704 {
0705 struct ncsi_dev_priv *ndp = nr->ndp;
0706 struct net_device *ndev = ndp->ndev.dev;
0707 const struct net_device_ops *ops = ndev->netdev_ops;
0708 struct ncsi_rsp_oem_pkt *rsp;
0709 struct sockaddr saddr;
0710 int ret = 0;
0711
0712
0713 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0714
0715 saddr.sa_family = ndev->type;
0716 ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
0717 memcpy(saddr.sa_data, &rsp->data[INTEL_MAC_ADDR_OFFSET], ETH_ALEN);
0718
0719 eth_addr_inc((u8 *)saddr.sa_data);
0720 if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
0721 return -ENXIO;
0722
0723
0724 ndp->gma_flag = 1;
0725
0726 ret = ops->ndo_set_mac_address(ndev, &saddr);
0727 if (ret < 0)
0728 netdev_warn(ndev,
0729 "NCSI: 'Writing mac address to device failed\n");
0730
0731 return ret;
0732 }
0733
0734
0735 static int ncsi_rsp_handler_oem_intel(struct ncsi_request *nr)
0736 {
0737 struct ncsi_rsp_oem_intel_pkt *intel;
0738 struct ncsi_rsp_oem_pkt *rsp;
0739
0740
0741 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0742 intel = (struct ncsi_rsp_oem_intel_pkt *)(rsp->data);
0743
0744 if (intel->cmd == NCSI_OEM_INTEL_CMD_GMA)
0745 return ncsi_rsp_handler_oem_intel_gma(nr);
0746
0747 return 0;
0748 }
0749
0750 static struct ncsi_rsp_oem_handler {
0751 unsigned int mfr_id;
0752 int (*handler)(struct ncsi_request *nr);
0753 } ncsi_rsp_oem_handlers[] = {
0754 { NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
0755 { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm },
0756 { NCSI_OEM_MFR_INTEL_ID, ncsi_rsp_handler_oem_intel }
0757 };
0758
0759
0760 static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
0761 {
0762 struct ncsi_rsp_oem_handler *nrh = NULL;
0763 struct ncsi_rsp_oem_pkt *rsp;
0764 unsigned int mfr_id, i;
0765
0766
0767 rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0768 mfr_id = ntohl(rsp->mfr_id);
0769
0770
0771 for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
0772 if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
0773 if (ncsi_rsp_oem_handlers[i].handler)
0774 nrh = &ncsi_rsp_oem_handlers[i];
0775 else
0776 nrh = NULL;
0777
0778 break;
0779 }
0780 }
0781
0782 if (!nrh) {
0783 netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
0784 mfr_id);
0785 return -ENOENT;
0786 }
0787
0788
0789 return nrh->handler(nr);
0790 }
0791
0792 static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
0793 {
0794 struct ncsi_rsp_gvi_pkt *rsp;
0795 struct ncsi_dev_priv *ndp = nr->ndp;
0796 struct ncsi_channel *nc;
0797 struct ncsi_channel_version *ncv;
0798 int i;
0799
0800
0801 rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
0802 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0803 NULL, &nc);
0804 if (!nc)
0805 return -ENODEV;
0806
0807
0808 ncv = &nc->version;
0809 ncv->version = ntohl(rsp->ncsi_version);
0810 ncv->alpha2 = rsp->alpha2;
0811 memcpy(ncv->fw_name, rsp->fw_name, 12);
0812 ncv->fw_version = ntohl(rsp->fw_version);
0813 for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
0814 ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
0815 ncv->mf_id = ntohl(rsp->mf_id);
0816
0817 return 0;
0818 }
0819
0820 static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
0821 {
0822 struct ncsi_rsp_gc_pkt *rsp;
0823 struct ncsi_dev_priv *ndp = nr->ndp;
0824 struct ncsi_channel *nc;
0825 size_t size;
0826
0827
0828 rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
0829 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0830 NULL, &nc);
0831 if (!nc)
0832 return -ENODEV;
0833
0834
0835 nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
0836 NCSI_CAP_GENERIC_MASK;
0837 nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
0838 NCSI_CAP_BC_MASK;
0839 nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
0840 NCSI_CAP_MC_MASK;
0841 nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
0842 nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
0843 NCSI_CAP_AEN_MASK;
0844 nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
0845 NCSI_CAP_VLAN_MASK;
0846
0847 size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
0848 nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
0849 if (!nc->mac_filter.addrs)
0850 return -ENOMEM;
0851 nc->mac_filter.n_uc = rsp->uc_cnt;
0852 nc->mac_filter.n_mc = rsp->mc_cnt;
0853 nc->mac_filter.n_mixed = rsp->mixed_cnt;
0854
0855 nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
0856 sizeof(*nc->vlan_filter.vids),
0857 GFP_ATOMIC);
0858 if (!nc->vlan_filter.vids)
0859 return -ENOMEM;
0860
0861
0862
0863 nc->vlan_filter.bitmap = U64_MAX;
0864 nc->vlan_filter.n_vids = rsp->vlan_cnt;
0865
0866 return 0;
0867 }
0868
0869 static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
0870 {
0871 struct ncsi_channel_vlan_filter *ncvf;
0872 struct ncsi_channel_mac_filter *ncmf;
0873 struct ncsi_dev_priv *ndp = nr->ndp;
0874 struct ncsi_rsp_gp_pkt *rsp;
0875 struct ncsi_channel *nc;
0876 unsigned short enable;
0877 unsigned char *pdata;
0878 unsigned long flags;
0879 void *bitmap;
0880 int i;
0881
0882
0883 rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
0884 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0885 NULL, &nc);
0886 if (!nc)
0887 return -ENODEV;
0888
0889
0890 if (ntohl(rsp->valid_modes) & 0x1) {
0891 nc->modes[NCSI_MODE_BC].enable = 1;
0892 nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
0893 }
0894 if (ntohl(rsp->valid_modes) & 0x2)
0895 nc->modes[NCSI_MODE_ENABLE].enable = 1;
0896 if (ntohl(rsp->valid_modes) & 0x4)
0897 nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
0898 if (ntohl(rsp->valid_modes) & 0x8)
0899 nc->modes[NCSI_MODE_MC].enable = 1;
0900
0901
0902 nc->modes[NCSI_MODE_LINK].enable = 1;
0903 nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
0904 nc->modes[NCSI_MODE_VLAN].enable = 1;
0905 nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
0906 nc->modes[NCSI_MODE_FC].enable = 1;
0907 nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
0908 nc->modes[NCSI_MODE_AEN].enable = 1;
0909 nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
0910
0911
0912 pdata = (unsigned char *)rsp + 48;
0913 enable = rsp->mac_enable;
0914 ncmf = &nc->mac_filter;
0915 spin_lock_irqsave(&nc->lock, flags);
0916 bitmap = &ncmf->bitmap;
0917 for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
0918 if (!(enable & (0x1 << i)))
0919 clear_bit(i, bitmap);
0920 else
0921 set_bit(i, bitmap);
0922
0923 memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
0924 }
0925 spin_unlock_irqrestore(&nc->lock, flags);
0926
0927
0928 enable = ntohs(rsp->vlan_enable);
0929 ncvf = &nc->vlan_filter;
0930 bitmap = &ncvf->bitmap;
0931 spin_lock_irqsave(&nc->lock, flags);
0932 for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
0933 if (!(enable & (0x1 << i)))
0934 clear_bit(i, bitmap);
0935 else
0936 set_bit(i, bitmap);
0937
0938 ncvf->vids[i] = ntohs(*(__be16 *)pdata);
0939 }
0940 spin_unlock_irqrestore(&nc->lock, flags);
0941
0942 return 0;
0943 }
0944
0945 static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
0946 {
0947 struct ncsi_rsp_gcps_pkt *rsp;
0948 struct ncsi_dev_priv *ndp = nr->ndp;
0949 struct ncsi_channel *nc;
0950 struct ncsi_channel_stats *ncs;
0951
0952
0953 rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
0954 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
0955 NULL, &nc);
0956 if (!nc)
0957 return -ENODEV;
0958
0959
0960 ncs = &nc->stats;
0961 ncs->hnc_cnt_hi = ntohl(rsp->cnt_hi);
0962 ncs->hnc_cnt_lo = ntohl(rsp->cnt_lo);
0963 ncs->hnc_rx_bytes = ntohl(rsp->rx_bytes);
0964 ncs->hnc_tx_bytes = ntohl(rsp->tx_bytes);
0965 ncs->hnc_rx_uc_pkts = ntohl(rsp->rx_uc_pkts);
0966 ncs->hnc_rx_mc_pkts = ntohl(rsp->rx_mc_pkts);
0967 ncs->hnc_rx_bc_pkts = ntohl(rsp->rx_bc_pkts);
0968 ncs->hnc_tx_uc_pkts = ntohl(rsp->tx_uc_pkts);
0969 ncs->hnc_tx_mc_pkts = ntohl(rsp->tx_mc_pkts);
0970 ncs->hnc_tx_bc_pkts = ntohl(rsp->tx_bc_pkts);
0971 ncs->hnc_fcs_err = ntohl(rsp->fcs_err);
0972 ncs->hnc_align_err = ntohl(rsp->align_err);
0973 ncs->hnc_false_carrier = ntohl(rsp->false_carrier);
0974 ncs->hnc_runt_pkts = ntohl(rsp->runt_pkts);
0975 ncs->hnc_jabber_pkts = ntohl(rsp->jabber_pkts);
0976 ncs->hnc_rx_pause_xon = ntohl(rsp->rx_pause_xon);
0977 ncs->hnc_rx_pause_xoff = ntohl(rsp->rx_pause_xoff);
0978 ncs->hnc_tx_pause_xon = ntohl(rsp->tx_pause_xon);
0979 ncs->hnc_tx_pause_xoff = ntohl(rsp->tx_pause_xoff);
0980 ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
0981 ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
0982 ncs->hnc_l_collision = ntohl(rsp->l_collision);
0983 ncs->hnc_e_collision = ntohl(rsp->e_collision);
0984 ncs->hnc_rx_ctl_frames = ntohl(rsp->rx_ctl_frames);
0985 ncs->hnc_rx_64_frames = ntohl(rsp->rx_64_frames);
0986 ncs->hnc_rx_127_frames = ntohl(rsp->rx_127_frames);
0987 ncs->hnc_rx_255_frames = ntohl(rsp->rx_255_frames);
0988 ncs->hnc_rx_511_frames = ntohl(rsp->rx_511_frames);
0989 ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
0990 ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
0991 ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
0992 ncs->hnc_tx_64_frames = ntohl(rsp->tx_64_frames);
0993 ncs->hnc_tx_127_frames = ntohl(rsp->tx_127_frames);
0994 ncs->hnc_tx_255_frames = ntohl(rsp->tx_255_frames);
0995 ncs->hnc_tx_511_frames = ntohl(rsp->tx_511_frames);
0996 ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
0997 ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
0998 ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
0999 ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
1000 ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts);
1001 ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
1002
1003 return 0;
1004 }
1005
1006 static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
1007 {
1008 struct ncsi_rsp_gns_pkt *rsp;
1009 struct ncsi_dev_priv *ndp = nr->ndp;
1010 struct ncsi_channel *nc;
1011 struct ncsi_channel_stats *ncs;
1012
1013
1014 rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
1015 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1016 NULL, &nc);
1017 if (!nc)
1018 return -ENODEV;
1019
1020
1021 ncs = &nc->stats;
1022 ncs->ncsi_rx_cmds = ntohl(rsp->rx_cmds);
1023 ncs->ncsi_dropped_cmds = ntohl(rsp->dropped_cmds);
1024 ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
1025 ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
1026 ncs->ncsi_rx_pkts = ntohl(rsp->rx_pkts);
1027 ncs->ncsi_tx_pkts = ntohl(rsp->tx_pkts);
1028 ncs->ncsi_tx_aen_pkts = ntohl(rsp->tx_aen_pkts);
1029
1030 return 0;
1031 }
1032
1033 static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
1034 {
1035 struct ncsi_rsp_gnpts_pkt *rsp;
1036 struct ncsi_dev_priv *ndp = nr->ndp;
1037 struct ncsi_channel *nc;
1038 struct ncsi_channel_stats *ncs;
1039
1040
1041 rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
1042 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1043 NULL, &nc);
1044 if (!nc)
1045 return -ENODEV;
1046
1047
1048 ncs = &nc->stats;
1049 ncs->pt_tx_pkts = ntohl(rsp->tx_pkts);
1050 ncs->pt_tx_dropped = ntohl(rsp->tx_dropped);
1051 ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
1052 ncs->pt_tx_us_err = ntohl(rsp->tx_us_err);
1053 ncs->pt_rx_pkts = ntohl(rsp->rx_pkts);
1054 ncs->pt_rx_dropped = ntohl(rsp->rx_dropped);
1055 ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
1056 ncs->pt_rx_us_err = ntohl(rsp->rx_us_err);
1057 ncs->pt_rx_os_err = ntohl(rsp->rx_os_err);
1058
1059 return 0;
1060 }
1061
1062 static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
1063 {
1064 struct ncsi_rsp_gps_pkt *rsp;
1065 struct ncsi_dev_priv *ndp = nr->ndp;
1066 struct ncsi_package *np;
1067
1068
1069 rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
1070 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1071 &np, NULL);
1072 if (!np)
1073 return -ENODEV;
1074
1075 return 0;
1076 }
1077
1078 static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
1079 {
1080 struct ncsi_rsp_gpuuid_pkt *rsp;
1081 struct ncsi_dev_priv *ndp = nr->ndp;
1082 struct ncsi_package *np;
1083
1084
1085 rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
1086 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1087 &np, NULL);
1088 if (!np)
1089 return -ENODEV;
1090
1091 memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
1092
1093 return 0;
1094 }
1095
1096 static int ncsi_rsp_handler_pldm(struct ncsi_request *nr)
1097 {
1098 return 0;
1099 }
1100
1101 static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
1102 {
1103 struct ncsi_dev_priv *ndp = nr->ndp;
1104 struct ncsi_rsp_pkt *rsp;
1105 struct ncsi_package *np;
1106 struct ncsi_channel *nc;
1107 int ret;
1108
1109
1110 rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
1111 ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1112 &np, &nc);
1113 if (!np)
1114 return -ENODEV;
1115
1116 ret = ncsi_send_netlink_rsp(nr, np, nc);
1117
1118 return ret;
1119 }
1120
1121 static struct ncsi_rsp_handler {
1122 unsigned char type;
1123 int payload;
1124 int (*handler)(struct ncsi_request *nr);
1125 } ncsi_rsp_handlers[] = {
1126 { NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis },
1127 { NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp },
1128 { NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp },
1129 { NCSI_PKT_RSP_EC, 4, ncsi_rsp_handler_ec },
1130 { NCSI_PKT_RSP_DC, 4, ncsi_rsp_handler_dc },
1131 { NCSI_PKT_RSP_RC, 4, ncsi_rsp_handler_rc },
1132 { NCSI_PKT_RSP_ECNT, 4, ncsi_rsp_handler_ecnt },
1133 { NCSI_PKT_RSP_DCNT, 4, ncsi_rsp_handler_dcnt },
1134 { NCSI_PKT_RSP_AE, 4, ncsi_rsp_handler_ae },
1135 { NCSI_PKT_RSP_SL, 4, ncsi_rsp_handler_sl },
1136 { NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
1137 { NCSI_PKT_RSP_SVF, 4, ncsi_rsp_handler_svf },
1138 { NCSI_PKT_RSP_EV, 4, ncsi_rsp_handler_ev },
1139 { NCSI_PKT_RSP_DV, 4, ncsi_rsp_handler_dv },
1140 { NCSI_PKT_RSP_SMA, 4, ncsi_rsp_handler_sma },
1141 { NCSI_PKT_RSP_EBF, 4, ncsi_rsp_handler_ebf },
1142 { NCSI_PKT_RSP_DBF, 4, ncsi_rsp_handler_dbf },
1143 { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf },
1144 { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf },
1145 { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc },
1146 { NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi },
1147 { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
1148 { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp },
1149 { NCSI_PKT_RSP_GCPS, 204, ncsi_rsp_handler_gcps },
1150 { NCSI_PKT_RSP_GNS, 32, ncsi_rsp_handler_gns },
1151 { NCSI_PKT_RSP_GNPTS, 48, ncsi_rsp_handler_gnpts },
1152 { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
1153 { NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
1154 { NCSI_PKT_RSP_PLDM, -1, ncsi_rsp_handler_pldm },
1155 { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid },
1156 { NCSI_PKT_RSP_QPNPR, -1, ncsi_rsp_handler_pldm },
1157 { NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm }
1158 };
1159
1160 int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
1161 struct packet_type *pt, struct net_device *orig_dev)
1162 {
1163 struct ncsi_rsp_handler *nrh = NULL;
1164 struct ncsi_dev *nd;
1165 struct ncsi_dev_priv *ndp;
1166 struct ncsi_request *nr;
1167 struct ncsi_pkt_hdr *hdr;
1168 unsigned long flags;
1169 int payload, i, ret;
1170
1171
1172 nd = ncsi_find_dev(orig_dev);
1173 ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
1174 if (!ndp)
1175 return -ENODEV;
1176
1177
1178 hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
1179 if (hdr->type == NCSI_PKT_AEN)
1180 return ncsi_aen_handler(ndp, skb);
1181
1182
1183 for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
1184 if (ncsi_rsp_handlers[i].type == hdr->type) {
1185 if (ncsi_rsp_handlers[i].handler)
1186 nrh = &ncsi_rsp_handlers[i];
1187 else
1188 nrh = NULL;
1189
1190 break;
1191 }
1192 }
1193
1194 if (!nrh) {
1195 netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
1196 hdr->type);
1197 return -ENOENT;
1198 }
1199
1200
1201 spin_lock_irqsave(&ndp->lock, flags);
1202 nr = &ndp->requests[hdr->id];
1203 if (!nr->used) {
1204 spin_unlock_irqrestore(&ndp->lock, flags);
1205 return -ENODEV;
1206 }
1207
1208 nr->rsp = skb;
1209 if (!nr->enabled) {
1210 spin_unlock_irqrestore(&ndp->lock, flags);
1211 ret = -ENOENT;
1212 goto out;
1213 }
1214
1215
1216 spin_unlock_irqrestore(&ndp->lock, flags);
1217 payload = nrh->payload;
1218 if (payload < 0)
1219 payload = ntohs(hdr->length);
1220 ret = ncsi_validate_rsp_pkt(nr, payload);
1221 if (ret) {
1222 netdev_warn(ndp->ndev.dev,
1223 "NCSI: 'bad' packet ignored for type 0x%x\n",
1224 hdr->type);
1225
1226 if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1227 if (ret == -EPERM)
1228 goto out_netlink;
1229 else
1230 ncsi_send_netlink_err(ndp->ndev.dev,
1231 nr->snd_seq,
1232 nr->snd_portid,
1233 &nr->nlhdr,
1234 ret);
1235 }
1236 goto out;
1237 }
1238
1239
1240 ret = nrh->handler(nr);
1241 if (ret)
1242 netdev_err(ndp->ndev.dev,
1243 "NCSI: Handler for packet type 0x%x returned %d\n",
1244 hdr->type, ret);
1245
1246 out_netlink:
1247 if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1248 ret = ncsi_rsp_handler_netlink(nr);
1249 if (ret) {
1250 netdev_err(ndp->ndev.dev,
1251 "NCSI: Netlink handler for packet type 0x%x returned %d\n",
1252 hdr->type, ret);
1253 }
1254 }
1255
1256 out:
1257 ncsi_free_request(nr);
1258 return ret;
1259 }