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