Linux Audio

Check our new training course

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