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