linux/net/ncsi/ncsi-rsp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright Gavin Shan, IBM Corporation 2016.
   4 */
   5
   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>
  12
  13#include <net/ncsi.h>
  14#include <net/net_namespace.h>
  15#include <net/sock.h>
  16#include <net/genetlink.h>
  17
  18#include "internal.h"
  19#include "ncsi-pkt.h"
  20#include "ncsi-netlink.h"
  21
  22static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
  23                                 unsigned short payload)
  24{
  25        struct ncsi_rsp_pkt_hdr *h;
  26        u32 checksum;
  27        __be32 *pchecksum;
  28
  29        /* Check NCSI packet header. We don't need validate
  30         * the packet type, which should have been checked
  31         * before calling this function.
  32         */
  33        h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);
  34
  35        if (h->common.revision != NCSI_PKT_REVISION) {
  36                netdev_dbg(nr->ndp->ndev.dev,
  37                           "NCSI: unsupported header revision\n");
  38                return -EINVAL;
  39        }
  40        if (ntohs(h->common.length) != payload) {
  41                netdev_dbg(nr->ndp->ndev.dev,
  42                           "NCSI: payload length mismatched\n");
  43                return -EINVAL;
  44        }
  45
  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));
  52                return -EPERM;
  53        }
  54
  55        /* Validate checksum, which might be zeroes if the
  56         * sender doesn't support checksum according to NCSI
  57         * specification.
  58         */
  59        pchecksum = (__be32 *)((void *)(h + 1) + ALIGN(payload, 4) - 4);
  60        if (ntohl(*pchecksum) == 0)
  61                return 0;
  62
  63        checksum = ncsi_calculate_checksum((unsigned char *)h,
  64                                           sizeof(*h) + payload - 4);
  65
  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));
  70                return -EINVAL;
  71        }
  72
  73        return 0;
  74}
  75
  76static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
  77{
  78        struct ncsi_rsp_pkt *rsp;
  79        struct ncsi_dev_priv *ndp = nr->ndp;
  80        struct ncsi_package *np;
  81        struct ncsi_channel *nc;
  82        unsigned char id;
  83
  84        rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  85        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, &np, &nc);
  86        if (!nc) {
  87                if (ndp->flags & NCSI_DEV_PROBED)
  88                        return -ENXIO;
  89
  90                id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
  91                nc = ncsi_add_channel(np, id);
  92        }
  93
  94        return nc ? 0 : -ENODEV;
  95}
  96
  97static int ncsi_rsp_handler_sp(struct ncsi_request *nr)
  98{
  99        struct ncsi_rsp_pkt *rsp;
 100        struct ncsi_dev_priv *ndp = nr->ndp;
 101        struct ncsi_package *np;
 102        unsigned char id;
 103
 104        /* Add the package if it's not existing. Otherwise,
 105         * to change the state of its child channels.
 106         */
 107        rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
 108        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 109                                      &np, NULL);
 110        if (!np) {
 111                if (ndp->flags & NCSI_DEV_PROBED)
 112                        return -ENXIO;
 113
 114                id = NCSI_PACKAGE_INDEX(rsp->rsp.common.channel);
 115                np = ncsi_add_package(ndp, id);
 116                if (!np)
 117                        return -ENODEV;
 118        }
 119
 120        return 0;
 121}
 122
 123static int ncsi_rsp_handler_dp(struct ncsi_request *nr)
 124{
 125        struct ncsi_rsp_pkt *rsp;
 126        struct ncsi_dev_priv *ndp = nr->ndp;
 127        struct ncsi_package *np;
 128        struct ncsi_channel *nc;
 129        unsigned long flags;
 130
 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,
 134                                      &np, NULL);
 135        if (!np)
 136                return -ENODEV;
 137
 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);
 143        }
 144
 145        return 0;
 146}
 147
 148static int ncsi_rsp_handler_ec(struct ncsi_request *nr)
 149{
 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;
 154
 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,
 158                                      NULL, &nc);
 159        if (!nc)
 160                return -ENODEV;
 161
 162        ncm = &nc->modes[NCSI_MODE_ENABLE];
 163        if (ncm->enable)
 164                return 0;
 165
 166        ncm->enable = 1;
 167        return 0;
 168}
 169
 170static int ncsi_rsp_handler_dc(struct ncsi_request *nr)
 171{
 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;
 176        int ret;
 177
 178        ret = ncsi_validate_rsp_pkt(nr, 4);
 179        if (ret)
 180                return ret;
 181
 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,
 185                                      NULL, &nc);
 186        if (!nc)
 187                return -ENODEV;
 188
 189        ncm = &nc->modes[NCSI_MODE_ENABLE];
 190        if (!ncm->enable)
 191                return 0;
 192
 193        ncm->enable = 0;
 194        return 0;
 195}
 196
 197static int ncsi_rsp_handler_rc(struct ncsi_request *nr)
 198{
 199        struct ncsi_rsp_pkt *rsp;
 200        struct ncsi_dev_priv *ndp = nr->ndp;
 201        struct ncsi_channel *nc;
 202        unsigned long flags;
 203
 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,
 207                                      NULL, &nc);
 208        if (!nc)
 209                return -ENODEV;
 210
 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);
 215
 216        return 0;
 217}
 218
 219static int ncsi_rsp_handler_ecnt(struct ncsi_request *nr)
 220{
 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;
 225
 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,
 229                                      NULL, &nc);
 230        if (!nc)
 231                return -ENODEV;
 232
 233        ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
 234        if (ncm->enable)
 235                return 0;
 236
 237        ncm->enable = 1;
 238        return 0;
 239}
 240
 241static int ncsi_rsp_handler_dcnt(struct ncsi_request *nr)
 242{
 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;
 247
 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,
 251                                      NULL, &nc);
 252        if (!nc)
 253                return -ENODEV;
 254
 255        ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
 256        if (!ncm->enable)
 257                return 0;
 258
 259        ncm->enable = 0;
 260        return 0;
 261}
 262
 263static int ncsi_rsp_handler_ae(struct ncsi_request *nr)
 264{
 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;
 270
 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,
 274                                      NULL, &nc);
 275        if (!nc)
 276                return -ENODEV;
 277
 278        /* Check if the AEN has been enabled */
 279        ncm = &nc->modes[NCSI_MODE_AEN];
 280        if (ncm->enable)
 281                return 0;
 282
 283        /* Update to AEN configuration */
 284        cmd = (struct ncsi_cmd_ae_pkt *)skb_network_header(nr->cmd);
 285        ncm->enable = 1;
 286        ncm->data[0] = cmd->mc_id;
 287        ncm->data[1] = ntohl(cmd->mode);
 288
 289        return 0;
 290}
 291
 292static int ncsi_rsp_handler_sl(struct ncsi_request *nr)
 293{
 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;
 299
 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,
 303                                      NULL, &nc);
 304        if (!nc)
 305                return -ENODEV;
 306
 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);
 311
 312        return 0;
 313}
 314
 315static int ncsi_rsp_handler_gls(struct ncsi_request *nr)
 316{
 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;
 321        unsigned long flags;
 322
 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,
 326                                      NULL, &nc);
 327        if (!nc)
 328                return -ENODEV;
 329
 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);
 334
 335        if (nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN)
 336                return 0;
 337
 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);
 342
 343        return 0;
 344}
 345
 346static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
 347{
 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;
 353        unsigned long flags;
 354        void *bitmap;
 355
 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,
 359                                      NULL, &nc);
 360        if (!nc)
 361                return -ENODEV;
 362
 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)
 366                return -ERANGE;
 367
 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;
 374        } else {
 375                set_bit(cmd->index - 1, bitmap);
 376                ncf->vids[cmd->index - 1] = ntohs(cmd->vlan);
 377        }
 378        spin_unlock_irqrestore(&nc->lock, flags);
 379
 380        return 0;
 381}
 382
 383static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
 384{
 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;
 390
 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,
 394                                      NULL, &nc);
 395        if (!nc)
 396                return -ENODEV;
 397
 398        /* Check if VLAN mode has been enabled */
 399        ncm = &nc->modes[NCSI_MODE_VLAN];
 400        if (ncm->enable)
 401                return 0;
 402
 403        /* Update to VLAN mode */
 404        cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
 405        ncm->enable = 1;
 406        ncm->data[0] = ntohl((__force __be32)cmd->mode);
 407
 408        return 0;
 409}
 410
 411static int ncsi_rsp_handler_dv(struct ncsi_request *nr)
 412{
 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;
 417
 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,
 421                                      NULL, &nc);
 422        if (!nc)
 423                return -ENODEV;
 424
 425        /* Check if VLAN mode has been enabled */
 426        ncm = &nc->modes[NCSI_MODE_VLAN];
 427        if (!ncm->enable)
 428                return 0;
 429
 430        /* Update to VLAN mode */
 431        ncm->enable = 0;
 432        return 0;
 433}
 434
 435static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
 436{
 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;
 442        unsigned long flags;
 443        void *bitmap;
 444        bool enabled;
 445        int index;
 446
 447
 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,
 451                                      NULL, &nc);
 452        if (!nc)
 453                return -ENODEV;
 454
 455        /* According to NCSI spec 1.01, the mixed filter table
 456         * isn't supported yet.
 457         */
 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;
 462
 463        if (cmd->index == 0 ||
 464            cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
 465                return -ERANGE;
 466
 467        index = (cmd->index - 1) * ETH_ALEN;
 468        spin_lock_irqsave(&nc->lock, flags);
 469        if (enabled) {
 470                set_bit(cmd->index - 1, bitmap);
 471                memcpy(&ncf->addrs[index], cmd->mac, ETH_ALEN);
 472        } else {
 473                clear_bit(cmd->index - 1, bitmap);
 474                eth_zero_addr(&ncf->addrs[index]);
 475        }
 476        spin_unlock_irqrestore(&nc->lock, flags);
 477
 478        return 0;
 479}
 480
 481static int ncsi_rsp_handler_ebf(struct ncsi_request *nr)
 482{
 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;
 488
 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);
 492        if (!nc)
 493                return -ENODEV;
 494
 495        /* Check if broadcast filter has been enabled */
 496        ncm = &nc->modes[NCSI_MODE_BC];
 497        if (ncm->enable)
 498                return 0;
 499
 500        /* Update to broadcast filter mode */
 501        cmd = (struct ncsi_cmd_ebf_pkt *)skb_network_header(nr->cmd);
 502        ncm->enable = 1;
 503        ncm->data[0] = ntohl(cmd->mode);
 504
 505        return 0;
 506}
 507
 508static int ncsi_rsp_handler_dbf(struct ncsi_request *nr)
 509{
 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;
 514
 515        rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
 516        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 517                                      NULL, &nc);
 518        if (!nc)
 519                return -ENODEV;
 520
 521        /* Check if broadcast filter isn't enabled */
 522        ncm = &nc->modes[NCSI_MODE_BC];
 523        if (!ncm->enable)
 524                return 0;
 525
 526        /* Update to broadcast filter mode */
 527        ncm->enable = 0;
 528        ncm->data[0] = 0;
 529
 530        return 0;
 531}
 532
 533static int ncsi_rsp_handler_egmf(struct ncsi_request *nr)
 534{
 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;
 540
 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,
 544                                      NULL, &nc);
 545        if (!nc)
 546                return -ENODEV;
 547
 548        /* Check if multicast filter has been enabled */
 549        ncm = &nc->modes[NCSI_MODE_MC];
 550        if (ncm->enable)
 551                return 0;
 552
 553        /* Update to multicast filter mode */
 554        cmd = (struct ncsi_cmd_egmf_pkt *)skb_network_header(nr->cmd);
 555        ncm->enable = 1;
 556        ncm->data[0] = ntohl(cmd->mode);
 557
 558        return 0;
 559}
 560
 561static int ncsi_rsp_handler_dgmf(struct ncsi_request *nr)
 562{
 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;
 567
 568        rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
 569        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 570                                      NULL, &nc);
 571        if (!nc)
 572                return -ENODEV;
 573
 574        /* Check if multicast filter has been enabled */
 575        ncm = &nc->modes[NCSI_MODE_MC];
 576        if (!ncm->enable)
 577                return 0;
 578
 579        /* Update to multicast filter mode */
 580        ncm->enable = 0;
 581        ncm->data[0] = 0;
 582
 583        return 0;
 584}
 585
 586static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
 587{
 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;
 593
 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,
 597                                      NULL, &nc);
 598        if (!nc)
 599                return -ENODEV;
 600
 601        /* Check if flow control has been enabled */
 602        ncm = &nc->modes[NCSI_MODE_FC];
 603        if (ncm->enable)
 604                return 0;
 605
 606        /* Update to flow control mode */
 607        cmd = (struct ncsi_cmd_snfc_pkt *)skb_network_header(nr->cmd);
 608        ncm->enable = 1;
 609        ncm->data[0] = cmd->mode;
 610
 611        return 0;
 612}
 613
 614/* Response handler for Mellanox command Get Mac Address */
 615static int ncsi_rsp_handler_oem_mlx_gma(struct ncsi_request *nr)
 616{
 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;
 622        int ret = 0;
 623
 624        /* Get the response header */
 625        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 626
 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 */
 631        ndp->gma_flag = 1;
 632
 633        ret = ops->ndo_set_mac_address(ndev, &saddr);
 634        if (ret < 0)
 635                netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
 636
 637        return ret;
 638}
 639
 640/* Response handler for Mellanox card */
 641static int ncsi_rsp_handler_oem_mlx(struct ncsi_request *nr)
 642{
 643        struct ncsi_rsp_oem_mlx_pkt *mlx;
 644        struct ncsi_rsp_oem_pkt *rsp;
 645
 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);
 649
 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);
 653        return 0;
 654}
 655
 656/* Response handler for Broadcom command Get Mac Address */
 657static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
 658{
 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;
 664        int ret = 0;
 665
 666        /* Get the response header */
 667        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 668
 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))
 675                return -ENXIO;
 676
 677        /* Set the flag for GMA command which should only be called once */
 678        ndp->gma_flag = 1;
 679
 680        ret = ops->ndo_set_mac_address(ndev, &saddr);
 681        if (ret < 0)
 682                netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
 683
 684        return ret;
 685}
 686
 687/* Response handler for Broadcom card */
 688static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
 689{
 690        struct ncsi_rsp_oem_bcm_pkt *bcm;
 691        struct ncsi_rsp_oem_pkt *rsp;
 692
 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);
 696
 697        if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
 698                return ncsi_rsp_handler_oem_bcm_gma(nr);
 699        return 0;
 700}
 701
 702/* Response handler for Intel card */
 703static int ncsi_rsp_handler_oem_intel(struct ncsi_request *nr)
 704{
 705        return 0;
 706}
 707
 708static struct ncsi_rsp_oem_handler {
 709        unsigned int    mfr_id;
 710        int             (*handler)(struct ncsi_request *nr);
 711} ncsi_rsp_oem_handlers[] = {
 712        { NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
 713        { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm },
 714        { NCSI_OEM_MFR_INTEL_ID, ncsi_rsp_handler_oem_intel }
 715};
 716
 717/* Response handler for OEM command */
 718static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
 719{
 720        struct ncsi_rsp_oem_handler *nrh = NULL;
 721        struct ncsi_rsp_oem_pkt *rsp;
 722        unsigned int mfr_id, i;
 723
 724        /* Get the response header */
 725        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 726        mfr_id = ntohl(rsp->mfr_id);
 727
 728        /* Check for manufacturer id and Find the handler */
 729        for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
 730                if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
 731                        if (ncsi_rsp_oem_handlers[i].handler)
 732                                nrh = &ncsi_rsp_oem_handlers[i];
 733                        else
 734                                nrh = NULL;
 735
 736                        break;
 737                }
 738        }
 739
 740        if (!nrh) {
 741                netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
 742                           mfr_id);
 743                return -ENOENT;
 744        }
 745
 746        /* Process the packet */
 747        return nrh->handler(nr);
 748}
 749
 750static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
 751{
 752        struct ncsi_rsp_gvi_pkt *rsp;
 753        struct ncsi_dev_priv *ndp = nr->ndp;
 754        struct ncsi_channel *nc;
 755        struct ncsi_channel_version *ncv;
 756        int i;
 757
 758        /* Find the channel */
 759        rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
 760        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 761                                      NULL, &nc);
 762        if (!nc)
 763                return -ENODEV;
 764
 765        /* Update to channel's version info */
 766        ncv = &nc->version;
 767        ncv->version = ntohl(rsp->ncsi_version);
 768        ncv->alpha2 = rsp->alpha2;
 769        memcpy(ncv->fw_name, rsp->fw_name, 12);
 770        ncv->fw_version = ntohl(rsp->fw_version);
 771        for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
 772                ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
 773        ncv->mf_id = ntohl(rsp->mf_id);
 774
 775        return 0;
 776}
 777
 778static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
 779{
 780        struct ncsi_rsp_gc_pkt *rsp;
 781        struct ncsi_dev_priv *ndp = nr->ndp;
 782        struct ncsi_channel *nc;
 783        size_t size;
 784
 785        /* Find the channel */
 786        rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
 787        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 788                                      NULL, &nc);
 789        if (!nc)
 790                return -ENODEV;
 791
 792        /* Update channel's capabilities */
 793        nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
 794                                         NCSI_CAP_GENERIC_MASK;
 795        nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
 796                                    NCSI_CAP_BC_MASK;
 797        nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
 798                                    NCSI_CAP_MC_MASK;
 799        nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
 800        nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
 801                                     NCSI_CAP_AEN_MASK;
 802        nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
 803                                      NCSI_CAP_VLAN_MASK;
 804
 805        size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
 806        nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
 807        if (!nc->mac_filter.addrs)
 808                return -ENOMEM;
 809        nc->mac_filter.n_uc = rsp->uc_cnt;
 810        nc->mac_filter.n_mc = rsp->mc_cnt;
 811        nc->mac_filter.n_mixed = rsp->mixed_cnt;
 812
 813        nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
 814                                       sizeof(*nc->vlan_filter.vids),
 815                                       GFP_ATOMIC);
 816        if (!nc->vlan_filter.vids)
 817                return -ENOMEM;
 818        /* Set VLAN filters active so they are cleared in the first
 819         * configuration state
 820         */
 821        nc->vlan_filter.bitmap = U64_MAX;
 822        nc->vlan_filter.n_vids = rsp->vlan_cnt;
 823
 824        return 0;
 825}
 826
 827static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
 828{
 829        struct ncsi_channel_vlan_filter *ncvf;
 830        struct ncsi_channel_mac_filter *ncmf;
 831        struct ncsi_dev_priv *ndp = nr->ndp;
 832        struct ncsi_rsp_gp_pkt *rsp;
 833        struct ncsi_channel *nc;
 834        unsigned short enable;
 835        unsigned char *pdata;
 836        unsigned long flags;
 837        void *bitmap;
 838        int i;
 839
 840        /* Find the channel */
 841        rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
 842        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 843                                      NULL, &nc);
 844        if (!nc)
 845                return -ENODEV;
 846
 847        /* Modes with explicit enabled indications */
 848        if (ntohl(rsp->valid_modes) & 0x1) {    /* BC filter mode */
 849                nc->modes[NCSI_MODE_BC].enable = 1;
 850                nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
 851        }
 852        if (ntohl(rsp->valid_modes) & 0x2)      /* Channel enabled */
 853                nc->modes[NCSI_MODE_ENABLE].enable = 1;
 854        if (ntohl(rsp->valid_modes) & 0x4)      /* Channel Tx enabled */
 855                nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
 856        if (ntohl(rsp->valid_modes) & 0x8)      /* MC filter mode */
 857                nc->modes[NCSI_MODE_MC].enable = 1;
 858
 859        /* Modes without explicit enabled indications */
 860        nc->modes[NCSI_MODE_LINK].enable = 1;
 861        nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
 862        nc->modes[NCSI_MODE_VLAN].enable = 1;
 863        nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
 864        nc->modes[NCSI_MODE_FC].enable = 1;
 865        nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
 866        nc->modes[NCSI_MODE_AEN].enable = 1;
 867        nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
 868
 869        /* MAC addresses filter table */
 870        pdata = (unsigned char *)rsp + 48;
 871        enable = rsp->mac_enable;
 872        ncmf = &nc->mac_filter;
 873        spin_lock_irqsave(&nc->lock, flags);
 874        bitmap = &ncmf->bitmap;
 875        for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
 876                if (!(enable & (0x1 << i)))
 877                        clear_bit(i, bitmap);
 878                else
 879                        set_bit(i, bitmap);
 880
 881                memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
 882        }
 883        spin_unlock_irqrestore(&nc->lock, flags);
 884
 885        /* VLAN filter table */
 886        enable = ntohs(rsp->vlan_enable);
 887        ncvf = &nc->vlan_filter;
 888        bitmap = &ncvf->bitmap;
 889        spin_lock_irqsave(&nc->lock, flags);
 890        for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
 891                if (!(enable & (0x1 << i)))
 892                        clear_bit(i, bitmap);
 893                else
 894                        set_bit(i, bitmap);
 895
 896                ncvf->vids[i] = ntohs(*(__be16 *)pdata);
 897        }
 898        spin_unlock_irqrestore(&nc->lock, flags);
 899
 900        return 0;
 901}
 902
 903static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
 904{
 905        struct ncsi_rsp_gcps_pkt *rsp;
 906        struct ncsi_dev_priv *ndp = nr->ndp;
 907        struct ncsi_channel *nc;
 908        struct ncsi_channel_stats *ncs;
 909
 910        /* Find the channel */
 911        rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
 912        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 913                                      NULL, &nc);
 914        if (!nc)
 915                return -ENODEV;
 916
 917        /* Update HNC's statistics */
 918        ncs = &nc->stats;
 919        ncs->hnc_cnt_hi         = ntohl(rsp->cnt_hi);
 920        ncs->hnc_cnt_lo         = ntohl(rsp->cnt_lo);
 921        ncs->hnc_rx_bytes       = ntohl(rsp->rx_bytes);
 922        ncs->hnc_tx_bytes       = ntohl(rsp->tx_bytes);
 923        ncs->hnc_rx_uc_pkts     = ntohl(rsp->rx_uc_pkts);
 924        ncs->hnc_rx_mc_pkts     = ntohl(rsp->rx_mc_pkts);
 925        ncs->hnc_rx_bc_pkts     = ntohl(rsp->rx_bc_pkts);
 926        ncs->hnc_tx_uc_pkts     = ntohl(rsp->tx_uc_pkts);
 927        ncs->hnc_tx_mc_pkts     = ntohl(rsp->tx_mc_pkts);
 928        ncs->hnc_tx_bc_pkts     = ntohl(rsp->tx_bc_pkts);
 929        ncs->hnc_fcs_err        = ntohl(rsp->fcs_err);
 930        ncs->hnc_align_err      = ntohl(rsp->align_err);
 931        ncs->hnc_false_carrier  = ntohl(rsp->false_carrier);
 932        ncs->hnc_runt_pkts      = ntohl(rsp->runt_pkts);
 933        ncs->hnc_jabber_pkts    = ntohl(rsp->jabber_pkts);
 934        ncs->hnc_rx_pause_xon   = ntohl(rsp->rx_pause_xon);
 935        ncs->hnc_rx_pause_xoff  = ntohl(rsp->rx_pause_xoff);
 936        ncs->hnc_tx_pause_xon   = ntohl(rsp->tx_pause_xon);
 937        ncs->hnc_tx_pause_xoff  = ntohl(rsp->tx_pause_xoff);
 938        ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
 939        ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
 940        ncs->hnc_l_collision    = ntohl(rsp->l_collision);
 941        ncs->hnc_e_collision    = ntohl(rsp->e_collision);
 942        ncs->hnc_rx_ctl_frames  = ntohl(rsp->rx_ctl_frames);
 943        ncs->hnc_rx_64_frames   = ntohl(rsp->rx_64_frames);
 944        ncs->hnc_rx_127_frames  = ntohl(rsp->rx_127_frames);
 945        ncs->hnc_rx_255_frames  = ntohl(rsp->rx_255_frames);
 946        ncs->hnc_rx_511_frames  = ntohl(rsp->rx_511_frames);
 947        ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
 948        ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
 949        ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
 950        ncs->hnc_tx_64_frames   = ntohl(rsp->tx_64_frames);
 951        ncs->hnc_tx_127_frames  = ntohl(rsp->tx_127_frames);
 952        ncs->hnc_tx_255_frames  = ntohl(rsp->tx_255_frames);
 953        ncs->hnc_tx_511_frames  = ntohl(rsp->tx_511_frames);
 954        ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
 955        ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
 956        ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
 957        ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
 958        ncs->hnc_rx_runt_pkts   = ntohl(rsp->rx_runt_pkts);
 959        ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
 960
 961        return 0;
 962}
 963
 964static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
 965{
 966        struct ncsi_rsp_gns_pkt *rsp;
 967        struct ncsi_dev_priv *ndp = nr->ndp;
 968        struct ncsi_channel *nc;
 969        struct ncsi_channel_stats *ncs;
 970
 971        /* Find the channel */
 972        rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
 973        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 974                                      NULL, &nc);
 975        if (!nc)
 976                return -ENODEV;
 977
 978        /* Update HNC's statistics */
 979        ncs = &nc->stats;
 980        ncs->ncsi_rx_cmds       = ntohl(rsp->rx_cmds);
 981        ncs->ncsi_dropped_cmds  = ntohl(rsp->dropped_cmds);
 982        ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
 983        ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
 984        ncs->ncsi_rx_pkts       = ntohl(rsp->rx_pkts);
 985        ncs->ncsi_tx_pkts       = ntohl(rsp->tx_pkts);
 986        ncs->ncsi_tx_aen_pkts   = ntohl(rsp->tx_aen_pkts);
 987
 988        return 0;
 989}
 990
 991static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
 992{
 993        struct ncsi_rsp_gnpts_pkt *rsp;
 994        struct ncsi_dev_priv *ndp = nr->ndp;
 995        struct ncsi_channel *nc;
 996        struct ncsi_channel_stats *ncs;
 997
 998        /* Find the channel */
 999        rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
1000        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1001                                      NULL, &nc);
1002        if (!nc)
1003                return -ENODEV;
1004
1005        /* Update HNC's statistics */
1006        ncs = &nc->stats;
1007        ncs->pt_tx_pkts        = ntohl(rsp->tx_pkts);
1008        ncs->pt_tx_dropped     = ntohl(rsp->tx_dropped);
1009        ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
1010        ncs->pt_tx_us_err      = ntohl(rsp->tx_us_err);
1011        ncs->pt_rx_pkts        = ntohl(rsp->rx_pkts);
1012        ncs->pt_rx_dropped     = ntohl(rsp->rx_dropped);
1013        ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
1014        ncs->pt_rx_us_err      = ntohl(rsp->rx_us_err);
1015        ncs->pt_rx_os_err      = ntohl(rsp->rx_os_err);
1016
1017        return 0;
1018}
1019
1020static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
1021{
1022        struct ncsi_rsp_gps_pkt *rsp;
1023        struct ncsi_dev_priv *ndp = nr->ndp;
1024        struct ncsi_package *np;
1025
1026        /* Find the package */
1027        rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
1028        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1029                                      &np, NULL);
1030        if (!np)
1031                return -ENODEV;
1032
1033        return 0;
1034}
1035
1036static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
1037{
1038        struct ncsi_rsp_gpuuid_pkt *rsp;
1039        struct ncsi_dev_priv *ndp = nr->ndp;
1040        struct ncsi_package *np;
1041
1042        /* Find the package */
1043        rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
1044        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1045                                      &np, NULL);
1046        if (!np)
1047                return -ENODEV;
1048
1049        memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
1050
1051        return 0;
1052}
1053
1054static int ncsi_rsp_handler_pldm(struct ncsi_request *nr)
1055{
1056        return 0;
1057}
1058
1059static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
1060{
1061        struct ncsi_dev_priv *ndp = nr->ndp;
1062        struct ncsi_rsp_pkt *rsp;
1063        struct ncsi_package *np;
1064        struct ncsi_channel *nc;
1065        int ret;
1066
1067        /* Find the package */
1068        rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
1069        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1070                                      &np, &nc);
1071        if (!np)
1072                return -ENODEV;
1073
1074        ret = ncsi_send_netlink_rsp(nr, np, nc);
1075
1076        return ret;
1077}
1078
1079static struct ncsi_rsp_handler {
1080        unsigned char   type;
1081        int             payload;
1082        int             (*handler)(struct ncsi_request *nr);
1083} ncsi_rsp_handlers[] = {
1084        { NCSI_PKT_RSP_CIS,     4, ncsi_rsp_handler_cis     },
1085        { NCSI_PKT_RSP_SP,      4, ncsi_rsp_handler_sp      },
1086        { NCSI_PKT_RSP_DP,      4, ncsi_rsp_handler_dp      },
1087        { NCSI_PKT_RSP_EC,      4, ncsi_rsp_handler_ec      },
1088        { NCSI_PKT_RSP_DC,      4, ncsi_rsp_handler_dc      },
1089        { NCSI_PKT_RSP_RC,      4, ncsi_rsp_handler_rc      },
1090        { NCSI_PKT_RSP_ECNT,    4, ncsi_rsp_handler_ecnt    },
1091        { NCSI_PKT_RSP_DCNT,    4, ncsi_rsp_handler_dcnt    },
1092        { NCSI_PKT_RSP_AE,      4, ncsi_rsp_handler_ae      },
1093        { NCSI_PKT_RSP_SL,      4, ncsi_rsp_handler_sl      },
1094        { NCSI_PKT_RSP_GLS,    16, ncsi_rsp_handler_gls     },
1095        { NCSI_PKT_RSP_SVF,     4, ncsi_rsp_handler_svf     },
1096        { NCSI_PKT_RSP_EV,      4, ncsi_rsp_handler_ev      },
1097        { NCSI_PKT_RSP_DV,      4, ncsi_rsp_handler_dv      },
1098        { NCSI_PKT_RSP_SMA,     4, ncsi_rsp_handler_sma     },
1099        { NCSI_PKT_RSP_EBF,     4, ncsi_rsp_handler_ebf     },
1100        { NCSI_PKT_RSP_DBF,     4, ncsi_rsp_handler_dbf     },
1101        { NCSI_PKT_RSP_EGMF,    4, ncsi_rsp_handler_egmf    },
1102        { NCSI_PKT_RSP_DGMF,    4, ncsi_rsp_handler_dgmf    },
1103        { NCSI_PKT_RSP_SNFC,    4, ncsi_rsp_handler_snfc    },
1104        { NCSI_PKT_RSP_GVI,    40, ncsi_rsp_handler_gvi     },
1105        { NCSI_PKT_RSP_GC,     32, ncsi_rsp_handler_gc      },
1106        { NCSI_PKT_RSP_GP,     -1, ncsi_rsp_handler_gp      },
1107        { NCSI_PKT_RSP_GCPS,  204, ncsi_rsp_handler_gcps    },
1108        { NCSI_PKT_RSP_GNS,    32, ncsi_rsp_handler_gns     },
1109        { NCSI_PKT_RSP_GNPTS,  48, ncsi_rsp_handler_gnpts   },
1110        { NCSI_PKT_RSP_GPS,     8, ncsi_rsp_handler_gps     },
1111        { NCSI_PKT_RSP_OEM,    -1, ncsi_rsp_handler_oem     },
1112        { NCSI_PKT_RSP_PLDM,   -1, ncsi_rsp_handler_pldm    },
1113        { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid  },
1114        { NCSI_PKT_RSP_QPNPR,  -1, ncsi_rsp_handler_pldm    },
1115        { NCSI_PKT_RSP_SNPR,   -1, ncsi_rsp_handler_pldm    }
1116};
1117
1118int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
1119                 struct packet_type *pt, struct net_device *orig_dev)
1120{
1121        struct ncsi_rsp_handler *nrh = NULL;
1122        struct ncsi_dev *nd;
1123        struct ncsi_dev_priv *ndp;
1124        struct ncsi_request *nr;
1125        struct ncsi_pkt_hdr *hdr;
1126        unsigned long flags;
1127        int payload, i, ret;
1128
1129        /* Find the NCSI device */
1130        nd = ncsi_find_dev(orig_dev);
1131        ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
1132        if (!ndp)
1133                return -ENODEV;
1134
1135        /* Check if it is AEN packet */
1136        hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
1137        if (hdr->type == NCSI_PKT_AEN)
1138                return ncsi_aen_handler(ndp, skb);
1139
1140        /* Find the handler */
1141        for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
1142                if (ncsi_rsp_handlers[i].type == hdr->type) {
1143                        if (ncsi_rsp_handlers[i].handler)
1144                                nrh = &ncsi_rsp_handlers[i];
1145                        else
1146                                nrh = NULL;
1147
1148                        break;
1149                }
1150        }
1151
1152        if (!nrh) {
1153                netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
1154                           hdr->type);
1155                return -ENOENT;
1156        }
1157
1158        /* Associate with the request */
1159        spin_lock_irqsave(&ndp->lock, flags);
1160        nr = &ndp->requests[hdr->id];
1161        if (!nr->used) {
1162                spin_unlock_irqrestore(&ndp->lock, flags);
1163                return -ENODEV;
1164        }
1165
1166        nr->rsp = skb;
1167        if (!nr->enabled) {
1168                spin_unlock_irqrestore(&ndp->lock, flags);
1169                ret = -ENOENT;
1170                goto out;
1171        }
1172
1173        /* Validate the packet */
1174        spin_unlock_irqrestore(&ndp->lock, flags);
1175        payload = nrh->payload;
1176        if (payload < 0)
1177                payload = ntohs(hdr->length);
1178        ret = ncsi_validate_rsp_pkt(nr, payload);
1179        if (ret) {
1180                netdev_warn(ndp->ndev.dev,
1181                            "NCSI: 'bad' packet ignored for type 0x%x\n",
1182                            hdr->type);
1183
1184                if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1185                        if (ret == -EPERM)
1186                                goto out_netlink;
1187                        else
1188                                ncsi_send_netlink_err(ndp->ndev.dev,
1189                                                      nr->snd_seq,
1190                                                      nr->snd_portid,
1191                                                      &nr->nlhdr,
1192                                                      ret);
1193                }
1194                goto out;
1195        }
1196
1197        /* Process the packet */
1198        ret = nrh->handler(nr);
1199        if (ret)
1200                netdev_err(ndp->ndev.dev,
1201                           "NCSI: Handler for packet type 0x%x returned %d\n",
1202                           hdr->type, ret);
1203
1204out_netlink:
1205        if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1206                ret = ncsi_rsp_handler_netlink(nr);
1207                if (ret) {
1208                        netdev_err(ndp->ndev.dev,
1209                                   "NCSI: Netlink handler for packet type 0x%x returned %d\n",
1210                                   hdr->type, ret);
1211                }
1212        }
1213
1214out:
1215        ncsi_free_request(nr);
1216        return ret;
1217}
1218