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(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                memset(&ncf->addrs[index], 0, ETH_ALEN);
 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        ret = ops->ndo_set_mac_address(ndev, &saddr);
 631        if (ret < 0)
 632                netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
 633
 634        return ret;
 635}
 636
 637/* Response handler for Mellanox card */
 638static int ncsi_rsp_handler_oem_mlx(struct ncsi_request *nr)
 639{
 640        struct ncsi_rsp_oem_mlx_pkt *mlx;
 641        struct ncsi_rsp_oem_pkt *rsp;
 642
 643        /* Get the response header */
 644        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 645        mlx = (struct ncsi_rsp_oem_mlx_pkt *)(rsp->data);
 646
 647        if (mlx->cmd == NCSI_OEM_MLX_CMD_GMA &&
 648            mlx->param == NCSI_OEM_MLX_CMD_GMA_PARAM)
 649                return ncsi_rsp_handler_oem_mlx_gma(nr);
 650        return 0;
 651}
 652
 653/* Response handler for Broadcom command Get Mac Address */
 654static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
 655{
 656        struct ncsi_dev_priv *ndp = nr->ndp;
 657        struct net_device *ndev = ndp->ndev.dev;
 658        const struct net_device_ops *ops = ndev->netdev_ops;
 659        struct ncsi_rsp_oem_pkt *rsp;
 660        struct sockaddr saddr;
 661        int ret = 0;
 662
 663        /* Get the response header */
 664        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 665
 666        saddr.sa_family = ndev->type;
 667        ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 668        memcpy(saddr.sa_data, &rsp->data[BCM_MAC_ADDR_OFFSET], ETH_ALEN);
 669        /* Increase mac address by 1 for BMC's address */
 670        eth_addr_inc((u8 *)saddr.sa_data);
 671        if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
 672                return -ENXIO;
 673
 674        ret = ops->ndo_set_mac_address(ndev, &saddr);
 675        if (ret < 0)
 676                netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
 677
 678        return ret;
 679}
 680
 681/* Response handler for Broadcom card */
 682static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
 683{
 684        struct ncsi_rsp_oem_bcm_pkt *bcm;
 685        struct ncsi_rsp_oem_pkt *rsp;
 686
 687        /* Get the response header */
 688        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 689        bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
 690
 691        if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
 692                return ncsi_rsp_handler_oem_bcm_gma(nr);
 693        return 0;
 694}
 695
 696static struct ncsi_rsp_oem_handler {
 697        unsigned int    mfr_id;
 698        int             (*handler)(struct ncsi_request *nr);
 699} ncsi_rsp_oem_handlers[] = {
 700        { NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
 701        { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm }
 702};
 703
 704/* Response handler for OEM command */
 705static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
 706{
 707        struct ncsi_rsp_oem_handler *nrh = NULL;
 708        struct ncsi_rsp_oem_pkt *rsp;
 709        unsigned int mfr_id, i;
 710
 711        /* Get the response header */
 712        rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
 713        mfr_id = ntohl(rsp->mfr_id);
 714
 715        /* Check for manufacturer id and Find the handler */
 716        for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
 717                if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
 718                        if (ncsi_rsp_oem_handlers[i].handler)
 719                                nrh = &ncsi_rsp_oem_handlers[i];
 720                        else
 721                                nrh = NULL;
 722
 723                        break;
 724                }
 725        }
 726
 727        if (!nrh) {
 728                netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
 729                           mfr_id);
 730                return -ENOENT;
 731        }
 732
 733        /* Process the packet */
 734        return nrh->handler(nr);
 735}
 736
 737static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
 738{
 739        struct ncsi_rsp_gvi_pkt *rsp;
 740        struct ncsi_dev_priv *ndp = nr->ndp;
 741        struct ncsi_channel *nc;
 742        struct ncsi_channel_version *ncv;
 743        int i;
 744
 745        /* Find the channel */
 746        rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
 747        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 748                                      NULL, &nc);
 749        if (!nc)
 750                return -ENODEV;
 751
 752        /* Update to channel's version info */
 753        ncv = &nc->version;
 754        ncv->version = ntohl(rsp->ncsi_version);
 755        ncv->alpha2 = rsp->alpha2;
 756        memcpy(ncv->fw_name, rsp->fw_name, 12);
 757        ncv->fw_version = ntohl(rsp->fw_version);
 758        for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
 759                ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
 760        ncv->mf_id = ntohl(rsp->mf_id);
 761
 762        return 0;
 763}
 764
 765static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
 766{
 767        struct ncsi_rsp_gc_pkt *rsp;
 768        struct ncsi_dev_priv *ndp = nr->ndp;
 769        struct ncsi_channel *nc;
 770        size_t size;
 771
 772        /* Find the channel */
 773        rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
 774        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 775                                      NULL, &nc);
 776        if (!nc)
 777                return -ENODEV;
 778
 779        /* Update channel's capabilities */
 780        nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
 781                                         NCSI_CAP_GENERIC_MASK;
 782        nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
 783                                    NCSI_CAP_BC_MASK;
 784        nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
 785                                    NCSI_CAP_MC_MASK;
 786        nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
 787        nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
 788                                     NCSI_CAP_AEN_MASK;
 789        nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
 790                                      NCSI_CAP_VLAN_MASK;
 791
 792        size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
 793        nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
 794        if (!nc->mac_filter.addrs)
 795                return -ENOMEM;
 796        nc->mac_filter.n_uc = rsp->uc_cnt;
 797        nc->mac_filter.n_mc = rsp->mc_cnt;
 798        nc->mac_filter.n_mixed = rsp->mixed_cnt;
 799
 800        nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
 801                                       sizeof(*nc->vlan_filter.vids),
 802                                       GFP_ATOMIC);
 803        if (!nc->vlan_filter.vids)
 804                return -ENOMEM;
 805        /* Set VLAN filters active so they are cleared in the first
 806         * configuration state
 807         */
 808        nc->vlan_filter.bitmap = U64_MAX;
 809        nc->vlan_filter.n_vids = rsp->vlan_cnt;
 810
 811        return 0;
 812}
 813
 814static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
 815{
 816        struct ncsi_channel_vlan_filter *ncvf;
 817        struct ncsi_channel_mac_filter *ncmf;
 818        struct ncsi_dev_priv *ndp = nr->ndp;
 819        struct ncsi_rsp_gp_pkt *rsp;
 820        struct ncsi_channel *nc;
 821        unsigned short enable;
 822        unsigned char *pdata;
 823        unsigned long flags;
 824        void *bitmap;
 825        int i;
 826
 827        /* Find the channel */
 828        rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
 829        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 830                                      NULL, &nc);
 831        if (!nc)
 832                return -ENODEV;
 833
 834        /* Modes with explicit enabled indications */
 835        if (ntohl(rsp->valid_modes) & 0x1) {    /* BC filter mode */
 836                nc->modes[NCSI_MODE_BC].enable = 1;
 837                nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
 838        }
 839        if (ntohl(rsp->valid_modes) & 0x2)      /* Channel enabled */
 840                nc->modes[NCSI_MODE_ENABLE].enable = 1;
 841        if (ntohl(rsp->valid_modes) & 0x4)      /* Channel Tx enabled */
 842                nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
 843        if (ntohl(rsp->valid_modes) & 0x8)      /* MC filter mode */
 844                nc->modes[NCSI_MODE_MC].enable = 1;
 845
 846        /* Modes without explicit enabled indications */
 847        nc->modes[NCSI_MODE_LINK].enable = 1;
 848        nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
 849        nc->modes[NCSI_MODE_VLAN].enable = 1;
 850        nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
 851        nc->modes[NCSI_MODE_FC].enable = 1;
 852        nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
 853        nc->modes[NCSI_MODE_AEN].enable = 1;
 854        nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
 855
 856        /* MAC addresses filter table */
 857        pdata = (unsigned char *)rsp + 48;
 858        enable = rsp->mac_enable;
 859        ncmf = &nc->mac_filter;
 860        spin_lock_irqsave(&nc->lock, flags);
 861        bitmap = &ncmf->bitmap;
 862        for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
 863                if (!(enable & (0x1 << i)))
 864                        clear_bit(i, bitmap);
 865                else
 866                        set_bit(i, bitmap);
 867
 868                memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
 869        }
 870        spin_unlock_irqrestore(&nc->lock, flags);
 871
 872        /* VLAN filter table */
 873        enable = ntohs(rsp->vlan_enable);
 874        ncvf = &nc->vlan_filter;
 875        bitmap = &ncvf->bitmap;
 876        spin_lock_irqsave(&nc->lock, flags);
 877        for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
 878                if (!(enable & (0x1 << i)))
 879                        clear_bit(i, bitmap);
 880                else
 881                        set_bit(i, bitmap);
 882
 883                ncvf->vids[i] = ntohs(*(__be16 *)pdata);
 884        }
 885        spin_unlock_irqrestore(&nc->lock, flags);
 886
 887        return 0;
 888}
 889
 890static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
 891{
 892        struct ncsi_rsp_gcps_pkt *rsp;
 893        struct ncsi_dev_priv *ndp = nr->ndp;
 894        struct ncsi_channel *nc;
 895        struct ncsi_channel_stats *ncs;
 896
 897        /* Find the channel */
 898        rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
 899        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 900                                      NULL, &nc);
 901        if (!nc)
 902                return -ENODEV;
 903
 904        /* Update HNC's statistics */
 905        ncs = &nc->stats;
 906        ncs->hnc_cnt_hi         = ntohl(rsp->cnt_hi);
 907        ncs->hnc_cnt_lo         = ntohl(rsp->cnt_lo);
 908        ncs->hnc_rx_bytes       = ntohl(rsp->rx_bytes);
 909        ncs->hnc_tx_bytes       = ntohl(rsp->tx_bytes);
 910        ncs->hnc_rx_uc_pkts     = ntohl(rsp->rx_uc_pkts);
 911        ncs->hnc_rx_mc_pkts     = ntohl(rsp->rx_mc_pkts);
 912        ncs->hnc_rx_bc_pkts     = ntohl(rsp->rx_bc_pkts);
 913        ncs->hnc_tx_uc_pkts     = ntohl(rsp->tx_uc_pkts);
 914        ncs->hnc_tx_mc_pkts     = ntohl(rsp->tx_mc_pkts);
 915        ncs->hnc_tx_bc_pkts     = ntohl(rsp->tx_bc_pkts);
 916        ncs->hnc_fcs_err        = ntohl(rsp->fcs_err);
 917        ncs->hnc_align_err      = ntohl(rsp->align_err);
 918        ncs->hnc_false_carrier  = ntohl(rsp->false_carrier);
 919        ncs->hnc_runt_pkts      = ntohl(rsp->runt_pkts);
 920        ncs->hnc_jabber_pkts    = ntohl(rsp->jabber_pkts);
 921        ncs->hnc_rx_pause_xon   = ntohl(rsp->rx_pause_xon);
 922        ncs->hnc_rx_pause_xoff  = ntohl(rsp->rx_pause_xoff);
 923        ncs->hnc_tx_pause_xon   = ntohl(rsp->tx_pause_xon);
 924        ncs->hnc_tx_pause_xoff  = ntohl(rsp->tx_pause_xoff);
 925        ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
 926        ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
 927        ncs->hnc_l_collision    = ntohl(rsp->l_collision);
 928        ncs->hnc_e_collision    = ntohl(rsp->e_collision);
 929        ncs->hnc_rx_ctl_frames  = ntohl(rsp->rx_ctl_frames);
 930        ncs->hnc_rx_64_frames   = ntohl(rsp->rx_64_frames);
 931        ncs->hnc_rx_127_frames  = ntohl(rsp->rx_127_frames);
 932        ncs->hnc_rx_255_frames  = ntohl(rsp->rx_255_frames);
 933        ncs->hnc_rx_511_frames  = ntohl(rsp->rx_511_frames);
 934        ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
 935        ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
 936        ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
 937        ncs->hnc_tx_64_frames   = ntohl(rsp->tx_64_frames);
 938        ncs->hnc_tx_127_frames  = ntohl(rsp->tx_127_frames);
 939        ncs->hnc_tx_255_frames  = ntohl(rsp->tx_255_frames);
 940        ncs->hnc_tx_511_frames  = ntohl(rsp->tx_511_frames);
 941        ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
 942        ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
 943        ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
 944        ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
 945        ncs->hnc_rx_runt_pkts   = ntohl(rsp->rx_runt_pkts);
 946        ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
 947
 948        return 0;
 949}
 950
 951static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
 952{
 953        struct ncsi_rsp_gns_pkt *rsp;
 954        struct ncsi_dev_priv *ndp = nr->ndp;
 955        struct ncsi_channel *nc;
 956        struct ncsi_channel_stats *ncs;
 957
 958        /* Find the channel */
 959        rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
 960        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 961                                      NULL, &nc);
 962        if (!nc)
 963                return -ENODEV;
 964
 965        /* Update HNC's statistics */
 966        ncs = &nc->stats;
 967        ncs->ncsi_rx_cmds       = ntohl(rsp->rx_cmds);
 968        ncs->ncsi_dropped_cmds  = ntohl(rsp->dropped_cmds);
 969        ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
 970        ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
 971        ncs->ncsi_rx_pkts       = ntohl(rsp->rx_pkts);
 972        ncs->ncsi_tx_pkts       = ntohl(rsp->tx_pkts);
 973        ncs->ncsi_tx_aen_pkts   = ntohl(rsp->tx_aen_pkts);
 974
 975        return 0;
 976}
 977
 978static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
 979{
 980        struct ncsi_rsp_gnpts_pkt *rsp;
 981        struct ncsi_dev_priv *ndp = nr->ndp;
 982        struct ncsi_channel *nc;
 983        struct ncsi_channel_stats *ncs;
 984
 985        /* Find the channel */
 986        rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
 987        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
 988                                      NULL, &nc);
 989        if (!nc)
 990                return -ENODEV;
 991
 992        /* Update HNC's statistics */
 993        ncs = &nc->stats;
 994        ncs->pt_tx_pkts        = ntohl(rsp->tx_pkts);
 995        ncs->pt_tx_dropped     = ntohl(rsp->tx_dropped);
 996        ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
 997        ncs->pt_tx_us_err      = ntohl(rsp->tx_us_err);
 998        ncs->pt_rx_pkts        = ntohl(rsp->rx_pkts);
 999        ncs->pt_rx_dropped     = ntohl(rsp->rx_dropped);
1000        ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
1001        ncs->pt_rx_us_err      = ntohl(rsp->rx_us_err);
1002        ncs->pt_rx_os_err      = ntohl(rsp->rx_os_err);
1003
1004        return 0;
1005}
1006
1007static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
1008{
1009        struct ncsi_rsp_gps_pkt *rsp;
1010        struct ncsi_dev_priv *ndp = nr->ndp;
1011        struct ncsi_package *np;
1012
1013        /* Find the package */
1014        rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
1015        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1016                                      &np, NULL);
1017        if (!np)
1018                return -ENODEV;
1019
1020        return 0;
1021}
1022
1023static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
1024{
1025        struct ncsi_rsp_gpuuid_pkt *rsp;
1026        struct ncsi_dev_priv *ndp = nr->ndp;
1027        struct ncsi_package *np;
1028
1029        /* Find the package */
1030        rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
1031        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1032                                      &np, NULL);
1033        if (!np)
1034                return -ENODEV;
1035
1036        memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
1037
1038        return 0;
1039}
1040
1041static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
1042{
1043        struct ncsi_dev_priv *ndp = nr->ndp;
1044        struct ncsi_rsp_pkt *rsp;
1045        struct ncsi_package *np;
1046        struct ncsi_channel *nc;
1047        int ret;
1048
1049        /* Find the package */
1050        rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
1051        ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
1052                                      &np, &nc);
1053        if (!np)
1054                return -ENODEV;
1055
1056        ret = ncsi_send_netlink_rsp(nr, np, nc);
1057
1058        return ret;
1059}
1060
1061static struct ncsi_rsp_handler {
1062        unsigned char   type;
1063        int             payload;
1064        int             (*handler)(struct ncsi_request *nr);
1065} ncsi_rsp_handlers[] = {
1066        { NCSI_PKT_RSP_CIS,     4, ncsi_rsp_handler_cis     },
1067        { NCSI_PKT_RSP_SP,      4, ncsi_rsp_handler_sp      },
1068        { NCSI_PKT_RSP_DP,      4, ncsi_rsp_handler_dp      },
1069        { NCSI_PKT_RSP_EC,      4, ncsi_rsp_handler_ec      },
1070        { NCSI_PKT_RSP_DC,      4, ncsi_rsp_handler_dc      },
1071        { NCSI_PKT_RSP_RC,      4, ncsi_rsp_handler_rc      },
1072        { NCSI_PKT_RSP_ECNT,    4, ncsi_rsp_handler_ecnt    },
1073        { NCSI_PKT_RSP_DCNT,    4, ncsi_rsp_handler_dcnt    },
1074        { NCSI_PKT_RSP_AE,      4, ncsi_rsp_handler_ae      },
1075        { NCSI_PKT_RSP_SL,      4, ncsi_rsp_handler_sl      },
1076        { NCSI_PKT_RSP_GLS,    16, ncsi_rsp_handler_gls     },
1077        { NCSI_PKT_RSP_SVF,     4, ncsi_rsp_handler_svf     },
1078        { NCSI_PKT_RSP_EV,      4, ncsi_rsp_handler_ev      },
1079        { NCSI_PKT_RSP_DV,      4, ncsi_rsp_handler_dv      },
1080        { NCSI_PKT_RSP_SMA,     4, ncsi_rsp_handler_sma     },
1081        { NCSI_PKT_RSP_EBF,     4, ncsi_rsp_handler_ebf     },
1082        { NCSI_PKT_RSP_DBF,     4, ncsi_rsp_handler_dbf     },
1083        { NCSI_PKT_RSP_EGMF,    4, ncsi_rsp_handler_egmf    },
1084        { NCSI_PKT_RSP_DGMF,    4, ncsi_rsp_handler_dgmf    },
1085        { NCSI_PKT_RSP_SNFC,    4, ncsi_rsp_handler_snfc    },
1086        { NCSI_PKT_RSP_GVI,    40, ncsi_rsp_handler_gvi     },
1087        { NCSI_PKT_RSP_GC,     32, ncsi_rsp_handler_gc      },
1088        { NCSI_PKT_RSP_GP,     -1, ncsi_rsp_handler_gp      },
1089        { NCSI_PKT_RSP_GCPS,  172, ncsi_rsp_handler_gcps    },
1090        { NCSI_PKT_RSP_GNS,   172, ncsi_rsp_handler_gns     },
1091        { NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts   },
1092        { NCSI_PKT_RSP_GPS,     8, ncsi_rsp_handler_gps     },
1093        { NCSI_PKT_RSP_OEM,    -1, ncsi_rsp_handler_oem     },
1094        { NCSI_PKT_RSP_PLDM,    0, NULL                     },
1095        { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid  }
1096};
1097
1098int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
1099                 struct packet_type *pt, struct net_device *orig_dev)
1100{
1101        struct ncsi_rsp_handler *nrh = NULL;
1102        struct ncsi_dev *nd;
1103        struct ncsi_dev_priv *ndp;
1104        struct ncsi_request *nr;
1105        struct ncsi_pkt_hdr *hdr;
1106        unsigned long flags;
1107        int payload, i, ret;
1108
1109        /* Find the NCSI device */
1110        nd = ncsi_find_dev(dev);
1111        ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
1112        if (!ndp)
1113                return -ENODEV;
1114
1115        /* Check if it is AEN packet */
1116        hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
1117        if (hdr->type == NCSI_PKT_AEN)
1118                return ncsi_aen_handler(ndp, skb);
1119
1120        /* Find the handler */
1121        for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
1122                if (ncsi_rsp_handlers[i].type == hdr->type) {
1123                        if (ncsi_rsp_handlers[i].handler)
1124                                nrh = &ncsi_rsp_handlers[i];
1125                        else
1126                                nrh = NULL;
1127
1128                        break;
1129                }
1130        }
1131
1132        if (!nrh) {
1133                netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
1134                           hdr->type);
1135                return -ENOENT;
1136        }
1137
1138        /* Associate with the request */
1139        spin_lock_irqsave(&ndp->lock, flags);
1140        nr = &ndp->requests[hdr->id];
1141        if (!nr->used) {
1142                spin_unlock_irqrestore(&ndp->lock, flags);
1143                return -ENODEV;
1144        }
1145
1146        nr->rsp = skb;
1147        if (!nr->enabled) {
1148                spin_unlock_irqrestore(&ndp->lock, flags);
1149                ret = -ENOENT;
1150                goto out;
1151        }
1152
1153        /* Validate the packet */
1154        spin_unlock_irqrestore(&ndp->lock, flags);
1155        payload = nrh->payload;
1156        if (payload < 0)
1157                payload = ntohs(hdr->length);
1158        ret = ncsi_validate_rsp_pkt(nr, payload);
1159        if (ret) {
1160                netdev_warn(ndp->ndev.dev,
1161                            "NCSI: 'bad' packet ignored for type 0x%x\n",
1162                            hdr->type);
1163
1164                if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1165                        if (ret == -EPERM)
1166                                goto out_netlink;
1167                        else
1168                                ncsi_send_netlink_err(ndp->ndev.dev,
1169                                                      nr->snd_seq,
1170                                                      nr->snd_portid,
1171                                                      &nr->nlhdr,
1172                                                      ret);
1173                }
1174                goto out;
1175        }
1176
1177        /* Process the packet */
1178        ret = nrh->handler(nr);
1179        if (ret)
1180                netdev_err(ndp->ndev.dev,
1181                           "NCSI: Handler for packet type 0x%x returned %d\n",
1182                           hdr->type, ret);
1183
1184out_netlink:
1185        if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
1186                ret = ncsi_rsp_handler_netlink(nr);
1187                if (ret) {
1188                        netdev_err(ndp->ndev.dev,
1189                                   "NCSI: Netlink handler for packet type 0x%x returned %d\n",
1190                                   hdr->type, ret);
1191                }
1192        }
1193
1194out:
1195        ncsi_free_request(nr);
1196        return ret;
1197}
1198