Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright Gavin Shan, IBM Corporation 2016.
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     /* Check NCSI packet header. We don't need validate
0030      * the packet type, which should have been checked
0031      * before calling this function.
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     /* Check on code and reason */
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     /* Validate checksum, which might be zeroes if the
0056      * sender doesn't support checksum according to NCSI
0057      * specification.
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     /* Add the package if it's not existing. Otherwise,
0105      * to change the state of its child channels.
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     /* Find the package */
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     /* Change state of all channels attached to the package */
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     /* Find the package and channel */
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     /* Find the package and channel */
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     /* Find the package and channel */
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     /* Update state for the specified channel */
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     /* Find the package and channel */
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     /* Find the package and channel */
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     /* Find the package and channel */
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     /* Check if the AEN has been enabled */
0279     ncm = &nc->modes[NCSI_MODE_AEN];
0280     if (ncm->enable)
0281         return 0;
0282 
0283     /* Update to AEN configuration */
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     /* Find the package and channel */
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     /* Find the package and channel */
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     /* Reset the channel monitor if it has been enabled */
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     /* Find the package and channel */
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     /* Add or remove the VLAN filter. Remember HW indexes from 1 */
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     /* Find the package and channel */
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     /* Check if VLAN mode has been enabled */
0399     ncm = &nc->modes[NCSI_MODE_VLAN];
0400     if (ncm->enable)
0401         return 0;
0402 
0403     /* Update to VLAN mode */
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     /* Find the package and channel */
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     /* Check if VLAN mode has been enabled */
0426     ncm = &nc->modes[NCSI_MODE_VLAN];
0427     if (!ncm->enable)
0428         return 0;
0429 
0430     /* Update to VLAN mode */
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     /* Find the package and channel */
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     /* According to NCSI spec 1.01, the mixed filter table
0456      * isn't supported yet.
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     /* Find the package and channel */
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     /* Check if broadcast filter has been enabled */
0496     ncm = &nc->modes[NCSI_MODE_BC];
0497     if (ncm->enable)
0498         return 0;
0499 
0500     /* Update to broadcast filter mode */
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     /* Check if broadcast filter isn't enabled */
0522     ncm = &nc->modes[NCSI_MODE_BC];
0523     if (!ncm->enable)
0524         return 0;
0525 
0526     /* Update to broadcast filter mode */
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     /* Find the channel */
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     /* Check if multicast filter has been enabled */
0549     ncm = &nc->modes[NCSI_MODE_MC];
0550     if (ncm->enable)
0551         return 0;
0552 
0553     /* Update to multicast filter mode */
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     /* Check if multicast filter has been enabled */
0575     ncm = &nc->modes[NCSI_MODE_MC];
0576     if (!ncm->enable)
0577         return 0;
0578 
0579     /* Update to multicast filter mode */
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     /* Find the channel */
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     /* Check if flow control has been enabled */
0602     ncm = &nc->modes[NCSI_MODE_FC];
0603     if (ncm->enable)
0604         return 0;
0605 
0606     /* Update to flow control mode */
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 /* Response handler for Mellanox command Get Mac Address */
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     /* Get the response header */
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     /* Set the flag for GMA command which should only be called once */
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 /* Response handler for Mellanox card */
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     /* Get the response header */
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 /* Response handler for Broadcom command Get Mac Address */
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     /* Get the response header */
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     /* Increase mac address by 1 for BMC's address */
0673     eth_addr_inc((u8 *)saddr.sa_data);
0674     if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
0675         return -ENXIO;
0676 
0677     /* Set the flag for GMA command which should only be called once */
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 /* Response handler for Broadcom card */
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     /* Get the response header */
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 /* Response handler for Intel command Get Mac Address */
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     /* Get the response header */
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     /* Increase mac address by 1 for BMC's address */
0719     eth_addr_inc((u8 *)saddr.sa_data);
0720     if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
0721         return -ENXIO;
0722 
0723     /* Set the flag for GMA command which should only be called once */
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 /* Response handler for Intel card */
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     /* Get the response header */
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 /* Response handler for OEM command */
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     /* Get the response header */
0767     rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
0768     mfr_id = ntohl(rsp->mfr_id);
0769 
0770     /* Check for manufacturer id and Find the handler */
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     /* Process the packet */
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     /* Find the channel */
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     /* Update to channel's version info */
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     /* Find the channel */
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     /* Update channel's capabilities */
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     /* Set VLAN filters active so they are cleared in the first
0861      * configuration state
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     /* Find the channel */
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     /* Modes with explicit enabled indications */
0890     if (ntohl(rsp->valid_modes) & 0x1) {    /* BC filter mode */
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)  /* Channel enabled */
0895         nc->modes[NCSI_MODE_ENABLE].enable = 1;
0896     if (ntohl(rsp->valid_modes) & 0x4)  /* Channel Tx enabled */
0897         nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
0898     if (ntohl(rsp->valid_modes) & 0x8)  /* MC filter mode */
0899         nc->modes[NCSI_MODE_MC].enable = 1;
0900 
0901     /* Modes without explicit enabled indications */
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     /* MAC addresses filter table */
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     /* VLAN filter table */
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     /* Find the channel */
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     /* Update HNC's statistics */
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     /* Find the channel */
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     /* Update HNC's statistics */
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     /* Find the channel */
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     /* Update HNC's statistics */
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     /* Find the package */
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     /* Find the package */
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     /* Find the package */
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     /* Find the NCSI device */
1172     nd = ncsi_find_dev(orig_dev);
1173     ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
1174     if (!ndp)
1175         return -ENODEV;
1176 
1177     /* Check if it is AEN packet */
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     /* Find the handler */
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     /* Associate with the request */
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     /* Validate the packet */
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     /* Process the packet */
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 }