root/net/ncsi/ncsi-rsp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ncsi_validate_rsp_pkt
  2. ncsi_rsp_handler_cis
  3. ncsi_rsp_handler_sp
  4. ncsi_rsp_handler_dp
  5. ncsi_rsp_handler_ec
  6. ncsi_rsp_handler_dc
  7. ncsi_rsp_handler_rc
  8. ncsi_rsp_handler_ecnt
  9. ncsi_rsp_handler_dcnt
  10. ncsi_rsp_handler_ae
  11. ncsi_rsp_handler_sl
  12. ncsi_rsp_handler_gls
  13. ncsi_rsp_handler_svf
  14. ncsi_rsp_handler_ev
  15. ncsi_rsp_handler_dv
  16. ncsi_rsp_handler_sma
  17. ncsi_rsp_handler_ebf
  18. ncsi_rsp_handler_dbf
  19. ncsi_rsp_handler_egmf
  20. ncsi_rsp_handler_dgmf
  21. ncsi_rsp_handler_snfc
  22. ncsi_rsp_handler_oem_mlx_gma
  23. ncsi_rsp_handler_oem_mlx
  24. ncsi_rsp_handler_oem_bcm_gma
  25. ncsi_rsp_handler_oem_bcm
  26. ncsi_rsp_handler_oem
  27. ncsi_rsp_handler_gvi
  28. ncsi_rsp_handler_gc
  29. ncsi_rsp_handler_gp
  30. ncsi_rsp_handler_gcps
  31. ncsi_rsp_handler_gns
  32. ncsi_rsp_handler_gnpts
  33. ncsi_rsp_handler_gps
  34. ncsi_rsp_handler_gpuuid
  35. ncsi_rsp_handler_pldm
  36. ncsi_rsp_handler_netlink
  37. ncsi_rcv_rsp

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

/* [<][>][^][v][top][bottom][index][help] */