pcie.c 84.5 KB
Newer Older
1 2 3
/*
 * Marvell Wireless LAN device driver: PCIE specific handling
 *
X
Xinming Hu 已提交
4
 * Copyright (C) 2011-2014, Marvell International Ltd.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
 *
 * This software file (the "File") is distributed by Marvell International
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 * (the "License").  You may use, redistribute and/or modify this File in
 * accordance with the terms and conditions of the License, a copy of which
 * is available by writing to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 * this warranty disclaimer.
 */

#include <linux/firmware.h>

#include "decl.h"
#include "ioctl.h"
#include "util.h"
#include "fw.h"
#include "main.h"
#include "wmm.h"
#include "11n.h"
#include "pcie.h"

#define PCIE_VERSION	"1.0"
#define DRV_NAME        "Marvell mwifiex PCIe"

static u8 user_rmmod;

static struct mwifiex_if_ops pcie_ops;

static struct semaphore add_remove_card_sem;

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
static const struct of_device_id mwifiex_pcie_of_match_table[] = {
	{ .compatible = "pci11ab,2b42" },
	{ .compatible = "pci1b4b,2b42" },
	{ }
};

static int mwifiex_pcie_probe_of(struct device *dev)
{
	if (!of_match_node(mwifiex_pcie_of_match_table, dev->of_node)) {
		dev_err(dev, "required compatible string missing\n");
		return -EINVAL;
	}

	return 0;
}

56 57
static int
mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
58
		       size_t size, int flags)
59
{
60
	struct pcie_service_card *card = adapter->card;
61
	struct mwifiex_dma_mapping mapping;
62

63 64
	mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
	if (pci_dma_mapping_error(card->dev, mapping.addr)) {
65
		mwifiex_dbg(adapter, ERROR, "failed to map pci memory!\n");
66 67
		return -1;
	}
68
	mapping.len = size;
69
	mwifiex_store_mapping(skb, &mapping);
70
	return 0;
71 72
}

73 74 75 76 77 78
static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
				     struct sk_buff *skb, int flags)
{
	struct pcie_service_card *card = adapter->card;
	struct mwifiex_dma_mapping mapping;

79
	mwifiex_get_mapping(skb, &mapping);
80 81 82
	pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
}

83 84 85 86 87 88 89
/*
 * This function reads sleep cookie and checks if FW is ready
 */
static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
{
	u32 *cookie_addr;
	struct pcie_service_card *card = adapter->card;
90 91 92 93
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

	if (!reg->sleep_cookie)
		return true;
94

95 96
	if (card->sleep_cookie_vbase) {
		cookie_addr = (u32 *)card->sleep_cookie_vbase;
97 98 99
		mwifiex_dbg(adapter, INFO,
			    "info: ACCESS_HW: sleep cookie=0x%x\n",
			    *cookie_addr);
100 101 102 103 104 105 106
		if (*cookie_addr == FW_AWAKE_COOKIE)
			return true;
	}

	return false;
}

107
#ifdef CONFIG_PM_SLEEP
108 109 110 111 112 113 114 115
/*
 * Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not suspended, this function allocates and sends a host
 * sleep activate request to the firmware and turns off the traffic.
 */
116
static int mwifiex_pcie_suspend(struct device *dev)
117 118 119
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
120
	struct pci_dev *pdev = to_pci_dev(dev);
121 122

	if (pdev) {
123
		card = pci_get_drvdata(pdev);
124 125 126 127 128 129 130 131 132 133 134
		if (!card || !card->adapter) {
			pr_err("Card or adapter structure is not valid\n");
			return 0;
		}
	} else {
		pr_err("PCIE device is not specified\n");
		return 0;
	}

	adapter = card->adapter;

135 136 137 138 139 140 141 142
	/* Enable the Host Sleep */
	if (!mwifiex_enable_hs(adapter)) {
		mwifiex_dbg(adapter, ERROR,
			    "cmd: failed to suspend\n");
		adapter->hs_enabling = false;
		return -EFAULT;
	}

143
	flush_workqueue(adapter->workqueue);
144 145 146

	/* Indicate device suspended */
	adapter->is_suspended = true;
147
	adapter->hs_enabling = false;
148 149 150 151 152 153 154 155 156 157 158 159

	return 0;
}

/*
 * Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not resumed, this function turns on the traffic and
 * sends a host sleep cancel request to the firmware.
 */
160
static int mwifiex_pcie_resume(struct device *dev)
161 162 163
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
164
	struct pci_dev *pdev = to_pci_dev(dev);
165 166

	if (pdev) {
167
		card = pci_get_drvdata(pdev);
168 169 170 171 172 173 174 175 176 177 178 179
		if (!card || !card->adapter) {
			pr_err("Card or adapter structure is not valid\n");
			return 0;
		}
	} else {
		pr_err("PCIE device is not specified\n");
		return 0;
	}

	adapter = card->adapter;

	if (!adapter->is_suspended) {
180 181
		mwifiex_dbg(adapter, WARN,
			    "Device already resumed\n");
182 183 184 185 186 187 188 189 190 191
		return 0;
	}

	adapter->is_suspended = false;

	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
			  MWIFIEX_ASYNC_CMD);

	return 0;
}
192
#endif
193

194 195 196 197 198 199 200 201 202 203
/*
 * This function probes an mwifiex device and registers it. It allocates
 * the card structure, enables PCIE function number and initiates the
 * device registration and initialization procedure by adding a logical
 * interface.
 */
static int mwifiex_pcie_probe(struct pci_dev *pdev,
					const struct pci_device_id *ent)
{
	struct pcie_service_card *card;
204
	int ret;
205 206

	pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
207
		 pdev->vendor, pdev->device, pdev->revision);
208

209
	card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
210
	if (!card)
211 212 213 214
		return -ENOMEM;

	card->dev = pdev;

215 216 217 218
	if (ent->driver_data) {
		struct mwifiex_pcie_device *data = (void *)ent->driver_data;
		card->pcie.reg = data->reg;
		card->pcie.blksz_fw_dl = data->blksz_fw_dl;
219
		card->pcie.tx_buf_size = data->tx_buf_size;
220
		card->pcie.can_dump_fw = data->can_dump_fw;
221 222
		card->pcie.mem_type_mapping_tbl = data->mem_type_mapping_tbl;
		card->pcie.num_mem_types = data->num_mem_types;
223
		card->pcie.can_ext_scan = data->can_ext_scan;
224 225
	}

226 227 228 229 230 231 232
	/* device tree node parsing and platform specific configuration*/
	if (pdev->dev.of_node) {
		ret = mwifiex_pcie_probe_of(&pdev->dev);
		if (ret)
			return ret;
	}

233
	if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
234
			     MWIFIEX_PCIE, &pdev->dev)) {
235 236 237 238 239 240 241 242 243 244 245 246 247 248
		pr_err("%s failed\n", __func__);
		return -1;
	}

	return 0;
}

/*
 * This function removes the interface and frees up the card structure.
 */
static void mwifiex_pcie_remove(struct pci_dev *pdev)
{
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;
249
	struct mwifiex_private *priv;
250 251 252 253 254 255 256 257 258

	card = pci_get_drvdata(pdev);
	if (!card)
		return;

	adapter = card->adapter;
	if (!adapter || !adapter->priv_num)
		return;

259
	if (user_rmmod && !adapter->mfg_mode) {
260
#ifdef CONFIG_PM_SLEEP
261
		if (adapter->is_suspended)
262
			mwifiex_pcie_resume(&pdev->dev);
263 264
#endif

265
		mwifiex_deauthenticate_all(adapter);
266

267
		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
268

269 270 271
		mwifiex_disable_auto_ds(priv);

		mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
272 273 274 275 276
	}

	mwifiex_remove_card(card->adapter, &add_remove_card_sem);
}

277 278 279 280 281 282 283 284
static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
{
	user_rmmod = 1;
	mwifiex_pcie_remove(pdev);

	return;
}

285
static const struct pci_device_id mwifiex_ids[] = {
286 287 288
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
289
		.driver_data = (unsigned long)&mwifiex_pcie8766,
290
	},
A
Avinash Patil 已提交
291 292 293
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
294 295 296 297 298 299
		.driver_data = (unsigned long)&mwifiex_pcie8897,
	},
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8997,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
		.driver_data = (unsigned long)&mwifiex_pcie8997,
A
Avinash Patil 已提交
300
	},
301 302 303 304 305
	{
		PCIE_VENDOR_ID_V2_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8997,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
		.driver_data = (unsigned long)&mwifiex_pcie8997,
	},
306 307 308 309 310
	{},
};

MODULE_DEVICE_TABLE(pci, mwifiex_ids);

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;

	if (!pdev) {
		pr_err("%s: PCIe device is not specified\n", __func__);
		return;
	}

	card = (struct pcie_service_card *)pci_get_drvdata(pdev);
	if (!card || !card->adapter) {
		pr_err("%s: Card or adapter structure is not valid (%ld)\n",
		       __func__, (long)card);
		return;
	}

	adapter = card->adapter;
	mwifiex_dbg(adapter, INFO,
		    "%s: vendor=0x%4.04x device=0x%4.04x rev=%d %s\n",
		    __func__, pdev->vendor, pdev->device,
		    pdev->revision,
		    prepare ? "Pre-FLR" : "Post-FLR");

	if (prepare) {
		/* Kernel would be performing FLR after this notification.
		 * Cleanup all software without cleaning anything related to
		 * PCIe and HW.
		 */
		mwifiex_do_flr(adapter, prepare);
		adapter->surprise_removed = true;
	} else {
		/* Kernel stores and restores PCIe function context before and
		 * after performing FLR respectively. Reconfigure the software
		 * and firmware including firmware redownload
		 */
		adapter->surprise_removed = false;
		mwifiex_do_flr(adapter, prepare);
	}
	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}

static const struct pci_error_handlers mwifiex_pcie_err_handler[] = {
		{ .reset_notify = mwifiex_pcie_reset_notify, },
};

357 358 359 360 361 362
#ifdef CONFIG_PM_SLEEP
/* Power Management Hooks */
static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
				mwifiex_pcie_resume);
#endif

363 364 365 366 367 368
/* PCI Device Driver */
static struct pci_driver __refdata mwifiex_pcie = {
	.name     = "mwifiex_pcie",
	.id_table = mwifiex_ids,
	.probe    = mwifiex_pcie_probe,
	.remove   = mwifiex_pcie_remove,
369 370 371 372
#ifdef CONFIG_PM_SLEEP
	.driver   = {
		.pm = &mwifiex_pcie_pm_ops,
	},
373
#endif
374
	.shutdown = mwifiex_pcie_shutdown,
375
	.err_handler = mwifiex_pcie_err_handler,
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
};

/*
 * This function writes data into PCIE card register.
 */
static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
{
	struct pcie_service_card *card = adapter->card;

	iowrite32(data, card->pci_mmap1 + reg);

	return 0;
}

/*
 * This function reads data from PCIE card register.
 */
static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
{
	struct pcie_service_card *card = adapter->card;

	*data = ioread32(card->pci_mmap1 + reg);
398 399
	if (*data == 0xffffffff)
		return 0xffffffff;
400 401 402 403

	return 0;
}

404 405 406 407 408 409 410 411 412 413 414
/* This function reads u8 data from PCIE card register. */
static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
				 int reg, u8 *data)
{
	struct pcie_service_card *card = adapter->card;

	*data = ioread8(card->pci_mmap1 + reg);

	return 0;
}

415
/*
416
 * This function adds delay loop to ensure FW is awake before proceeding.
417
 */
418
static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
419 420 421
{
	int i = 0;

422
	while (mwifiex_pcie_ok_to_access_hw(adapter)) {
423
		i++;
424
		usleep_range(10, 20);
425
		/* 50ms max wait */
426
		if (i == 5000)
427 428 429
			break;
	}

430 431 432
	return;
}

433 434 435 436 437 438 439 440 441 442 443 444
static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
					   u32 max_delay_loop_cnt)
{
	struct pcie_service_card *card = adapter->card;
	u8 *buffer;
	u32 sleep_cookie, count;

	for (count = 0; count < max_delay_loop_cnt; count++) {
		buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
		sleep_cookie = *(u32 *)buffer;

		if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
445 446
			mwifiex_dbg(adapter, INFO,
				    "sleep cookie found at count %d\n", count);
447 448 449 450 451 452
			break;
		}
		usleep_range(20, 30);
	}

	if (count >= max_delay_loop_cnt)
453 454
		mwifiex_dbg(adapter, INFO,
			    "max count reached while accessing sleep cookie\n");
455 456
}

457 458 459 460 461 462 463
/* This function wakes up the card by reading fw_status register. */
static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
{
	u32 fw_status;
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

464 465
	mwifiex_dbg(adapter, EVENT,
		    "event: Wakeup device...\n");
466

467 468 469 470 471
	if (reg->sleep_cookie)
		mwifiex_pcie_dev_wakeup_delay(adapter);

	/* Reading fw_status register will wakeup device */
	if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
472 473
		mwifiex_dbg(adapter, ERROR,
			    "Reading fw_status register failed\n");
474 475 476
		return -1;
	}

477 478
	if (reg->sleep_cookie) {
		mwifiex_pcie_dev_wakeup_delay(adapter);
479 480
		mwifiex_dbg(adapter, INFO,
			    "PCIE wakeup: Setting PS_STATE_AWAKE\n");
481 482
		adapter->ps_state = PS_STATE_AWAKE;
	}
483 484 485 486 487 488 489 490 491 492 493

	return 0;
}

/*
 * This function is called after the card has woken up.
 *
 * The card configuration register is reset.
 */
static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
{
494 495
	mwifiex_dbg(adapter, CMD,
		    "cmd: Wakeup device completed\n");
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510

	return 0;
}

/*
 * This function disables the host interrupt.
 *
 * The host interrupt mask is read, the disable bit is reset and
 * written back to the card host interrupt mask register.
 */
static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
{
	if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
				      0x00000000)) {
511 512
			mwifiex_dbg(adapter, ERROR,
				    "Disable host interrupt failed\n");
513 514 515 516 517 518 519
			return -1;
		}
	}

	return 0;
}

520 521 522 523 524
static void mwifiex_pcie_disable_host_int_noerr(struct mwifiex_adapter *adapter)
{
	WARN_ON(mwifiex_pcie_disable_host_int(adapter));
}

525 526 527 528 529 530 531 532 533 534 535 536
/*
 * This function enables the host interrupt.
 *
 * The host interrupt enable mask is written to the card
 * host interrupt mask register.
 */
static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
{
	if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		/* Simply write the mask to the register */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
				      HOST_INTR_MASK)) {
537 538
			mwifiex_dbg(adapter, ERROR,
				    "Enable host interrupt failed\n");
539 540 541 542 543 544 545 546
			return -1;
		}
	}

	return 0;
}

/*
547 548 549 550 551
 * This function initializes TX buffer ring descriptors
 */
static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
A
Avinash Patil 已提交
552
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
553
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
554
	struct mwifiex_pfu_buf_desc *desc2;
555 556 557 558
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		card->tx_buf_list[i] = NULL;
A
Avinash Patil 已提交
559 560 561 562 563 564 565 566 567 568 569
		if (reg->pfu_enabled) {
			card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
					     (sizeof(*desc2) * i);
			desc2 = card->txbd_ring[i];
			memset(desc2, 0, sizeof(*desc2));
		} else {
			card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
					     (sizeof(*desc) * i);
			desc = card->txbd_ring[i];
			memset(desc, 0, sizeof(*desc));
		}
570 571 572 573 574 575 576 577 578 579 580 581
	}

	return 0;
}

/* This function initializes RX buffer ring descriptors. Each SKB is allocated
 * here and after mapping PCI memory, its physical address is assigned to
 * PCIE Rx buffer descriptor's physical address.
 */
static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
A
Avinash Patil 已提交
582
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
583 584
	struct sk_buff *skb;
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
585
	struct mwifiex_pfu_buf_desc *desc2;
586 587 588 589 590
	dma_addr_t buf_pa;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		/* Allocate skb here so that firmware can DMA data from it */
591
		skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
592
						  GFP_KERNEL);
593
		if (!skb) {
594 595
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb for RX ring.\n");
596 597 598 599 600 601 602 603 604
			kfree(card->rxbd_ring_vbase);
			return -ENOMEM;
		}

		if (mwifiex_map_pci_memory(adapter, skb,
					   MWIFIEX_RX_DATA_BUF_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;

605
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
606

607 608 609 610
		mwifiex_dbg(adapter, INFO,
			    "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
			    skb, skb->len, skb->data, (u32)buf_pa,
			    (u32)((u64)buf_pa >> 32));
611 612

		card->rx_buf_list[i] = skb;
A
Avinash Patil 已提交
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
		if (reg->pfu_enabled) {
			card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
					     (sizeof(*desc2) * i);
			desc2 = card->rxbd_ring[i];
			desc2->paddr = buf_pa;
			desc2->len = (u16)skb->len;
			desc2->frag_len = (u16)skb->len;
			desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
			desc2->offset = 0;
		} else {
			card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
					     (sizeof(*desc) * i));
			desc = card->rxbd_ring[i];
			desc->paddr = buf_pa;
			desc->len = (u16)skb->len;
			desc->flags = 0;
		}
630 631 632 633 634 635 636 637 638 639 640 641
	}

	return 0;
}

/* This function initializes event buffer ring descriptors. Each SKB is
 * allocated here and after mapping PCI memory, its physical address is assigned
 * to PCIE Rx buffer descriptor's physical address
 */
static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
642
	struct mwifiex_evt_buf_desc *desc;
643 644 645 646 647 648 649 650
	struct sk_buff *skb;
	dma_addr_t buf_pa;
	int i;

	for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
		/* Allocate skb here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MAX_EVENT_SIZE);
		if (!skb) {
651 652
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb for EVENT buf.\n");
653 654 655 656 657 658 659 660 661
			kfree(card->evtbd_ring_vbase);
			return -ENOMEM;
		}
		skb_put(skb, MAX_EVENT_SIZE);

		if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;

662
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
663

664 665 666 667
		mwifiex_dbg(adapter, EVENT,
			    "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
			    skb, skb->len, skb->data, (u32)buf_pa,
			    (u32)((u64)buf_pa >> 32));
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686

		card->evt_buf_list[i] = skb;
		card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
				      (sizeof(*desc) * i));
		desc = card->evtbd_ring[i];
		desc->paddr = buf_pa;
		desc->len = (u16)skb->len;
		desc->flags = 0;
	}

	return 0;
}

/* This function cleans up TX buffer rings. If any of the buffer list has valid
 * SKB address, associated SKB is freed.
 */
static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
A
Avinash Patil 已提交
687
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
688 689
	struct sk_buff *skb;
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
690
	struct mwifiex_pfu_buf_desc *desc2;
691 692 693
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
A
Avinash Patil 已提交
694 695 696 697
		if (reg->pfu_enabled) {
			desc2 = card->txbd_ring[i];
			if (card->tx_buf_list[i]) {
				skb = card->tx_buf_list[i];
698 699
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_TODEVICE);
A
Avinash Patil 已提交
700 701 702 703 704 705 706
				dev_kfree_skb_any(skb);
			}
			memset(desc2, 0, sizeof(*desc2));
		} else {
			desc = card->txbd_ring[i];
			if (card->tx_buf_list[i]) {
				skb = card->tx_buf_list[i];
707 708
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_TODEVICE);
A
Avinash Patil 已提交
709 710 711
				dev_kfree_skb_any(skb);
			}
			memset(desc, 0, sizeof(*desc));
712 713 714 715 716 717 718 719 720 721 722 723 724
		}
		card->tx_buf_list[i] = NULL;
	}

	return;
}

/* This function cleans up RX buffer rings. If any of the buffer list has valid
 * SKB address, associated SKB is freed.
 */
static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
A
Avinash Patil 已提交
725
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
726
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
727
	struct mwifiex_pfu_buf_desc *desc2;
728 729 730 731
	struct sk_buff *skb;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
A
Avinash Patil 已提交
732 733 734 735
		if (reg->pfu_enabled) {
			desc2 = card->rxbd_ring[i];
			if (card->rx_buf_list[i]) {
				skb = card->rx_buf_list[i];
736 737
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_FROMDEVICE);
A
Avinash Patil 已提交
738 739 740 741 742 743 744
				dev_kfree_skb_any(skb);
			}
			memset(desc2, 0, sizeof(*desc2));
		} else {
			desc = card->rxbd_ring[i];
			if (card->rx_buf_list[i]) {
				skb = card->rx_buf_list[i];
745 746
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_FROMDEVICE);
A
Avinash Patil 已提交
747 748 749
				dev_kfree_skb_any(skb);
			}
			memset(desc, 0, sizeof(*desc));
750
		}
A
Avinash Patil 已提交
751
		card->rx_buf_list[i] = NULL;
752 753 754 755 756 757 758 759 760 761 762
	}

	return;
}

/* This function cleans up event buffer rings. If any of the buffer list has
 * valid SKB address, associated SKB is freed.
 */
static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
763
	struct mwifiex_evt_buf_desc *desc;
764 765 766 767 768 769 770
	struct sk_buff *skb;
	int i;

	for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
		desc = card->evtbd_ring[i];
		if (card->evt_buf_list[i]) {
			skb = card->evt_buf_list[i];
771 772
			mwifiex_unmap_pci_memory(adapter, skb,
						 PCI_DMA_FROMDEVICE);
773 774 775 776 777 778 779 780 781 782
			dev_kfree_skb_any(skb);
		}
		card->evt_buf_list[i] = NULL;
		memset(desc, 0, sizeof(*desc));
	}

	return;
}

/* This function creates buffer descriptor ring for TX
783 784 785 786
 */
static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
787
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
788 789 790 791 792 793 794

	/*
	 * driver maintaines the write pointer and firmware maintaines the read
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->txbd_wrptr = 0;
A
Avinash Patil 已提交
795 796 797 798 799

	if (reg->pfu_enabled)
		card->txbd_rdptr = 0;
	else
		card->txbd_rdptr |= reg->tx_rollover_ind;
800 801 802

	/* allocate shared memory for the BD ring and divide the same in to
	   several descriptors */
A
Avinash Patil 已提交
803 804 805 806 807 808 809
	if (reg->pfu_enabled)
		card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
				       MWIFIEX_MAX_TXRX_BD;
	else
		card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
				       MWIFIEX_MAX_TXRX_BD;

810 811 812
	mwifiex_dbg(adapter, INFO,
		    "info: txbd_ring: Allocating %d bytes\n",
		    card->txbd_ring_size);
813 814 815
	card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
						     card->txbd_ring_size,
						     &card->txbd_ring_pbase);
816
	if (!card->txbd_ring_vbase) {
817 818 819
		mwifiex_dbg(adapter, ERROR,
			    "allocate consistent memory (%d bytes) failed!\n",
			    card->txbd_ring_size);
820
		return -ENOMEM;
821
	}
822 823 824 825 826
	mwifiex_dbg(adapter, DATA,
		    "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
		    card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
		    (u32)((u64)card->txbd_ring_pbase >> 32),
		    card->txbd_ring_size);
827

828
	return mwifiex_init_txq_ring(adapter);
829 830 831 832 833
}

static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
834
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
835

836
	mwifiex_cleanup_txq_ring(adapter);
837

838 839 840 841
	if (card->txbd_ring_vbase)
		pci_free_consistent(card->dev, card->txbd_ring_size,
				    card->txbd_ring_vbase,
				    card->txbd_ring_pbase);
842 843
	card->txbd_ring_size = 0;
	card->txbd_wrptr = 0;
844
	card->txbd_rdptr = 0 | reg->tx_rollover_ind;
845
	card->txbd_ring_vbase = NULL;
846
	card->txbd_ring_pbase = 0;
847 848 849 850 851 852 853 854 855 856

	return 0;
}

/*
 * This function creates buffer descriptor ring for RX
 */
static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
857
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
858 859 860 861 862 863 864

	/*
	 * driver maintaines the read pointer and firmware maintaines the write
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->rxbd_wrptr = 0;
865
	card->rxbd_rdptr = reg->rx_rollover_ind;
866

A
Avinash Patil 已提交
867 868 869 870 871 872 873
	if (reg->pfu_enabled)
		card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
				       MWIFIEX_MAX_TXRX_BD;
	else
		card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
				       MWIFIEX_MAX_TXRX_BD;

874 875 876
	mwifiex_dbg(adapter, INFO,
		    "info: rxbd_ring: Allocating %d bytes\n",
		    card->rxbd_ring_size);
877 878 879
	card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
						     card->rxbd_ring_size,
						     &card->rxbd_ring_pbase);
880
	if (!card->rxbd_ring_vbase) {
881 882 883
		mwifiex_dbg(adapter, ERROR,
			    "allocate consistent memory (%d bytes) failed!\n",
			    card->rxbd_ring_size);
884
		return -ENOMEM;
885 886
	}

887 888 889 890 891
	mwifiex_dbg(adapter, DATA,
		    "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
		    card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
		    (u32)((u64)card->rxbd_ring_pbase >> 32),
		    card->rxbd_ring_size);
892

893
	return mwifiex_init_rxq_ring(adapter);
894 895 896 897 898 899 900 901
}

/*
 * This function deletes Buffer descriptor ring for RX
 */
static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
902
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
903

904
	mwifiex_cleanup_rxq_ring(adapter);
905

906 907 908 909
	if (card->rxbd_ring_vbase)
		pci_free_consistent(card->dev, card->rxbd_ring_size,
				    card->rxbd_ring_vbase,
				    card->rxbd_ring_pbase);
910 911
	card->rxbd_ring_size = 0;
	card->rxbd_wrptr = 0;
912
	card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
913
	card->rxbd_ring_vbase = NULL;
914
	card->rxbd_ring_pbase = 0;
915 916 917 918 919 920 921 922 923 924

	return 0;
}

/*
 * This function creates buffer descriptor ring for Events
 */
static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
925
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
926 927 928 929 930 931 932

	/*
	 * driver maintaines the read pointer and firmware maintaines the write
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->evtbd_wrptr = 0;
933
	card->evtbd_rdptr = reg->evt_rollover_ind;
934

935
	card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
A
Avinash Patil 已提交
936 937
				MWIFIEX_MAX_EVT_BD;

938 939
	mwifiex_dbg(adapter, INFO,
		    "info: evtbd_ring: Allocating %d bytes\n",
940
		card->evtbd_ring_size);
941 942 943
	card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
						      card->evtbd_ring_size,
						      &card->evtbd_ring_pbase);
944
	if (!card->evtbd_ring_vbase) {
945 946 947
		mwifiex_dbg(adapter, ERROR,
			    "allocate consistent memory (%d bytes) failed!\n",
			    card->evtbd_ring_size);
948
		return -ENOMEM;
949 950
	}

951 952 953 954 955
	mwifiex_dbg(adapter, EVENT,
		    "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
		    card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
		    (u32)((u64)card->evtbd_ring_pbase >> 32),
		    card->evtbd_ring_size);
956

957
	return mwifiex_pcie_init_evt_ring(adapter);
958 959 960 961 962 963 964 965
}

/*
 * This function deletes Buffer descriptor ring for Events
 */
static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
966
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
967

968
	mwifiex_cleanup_evt_ring(adapter);
969

970 971 972 973
	if (card->evtbd_ring_vbase)
		pci_free_consistent(card->dev, card->evtbd_ring_size,
				    card->evtbd_ring_vbase,
				    card->evtbd_ring_pbase);
974
	card->evtbd_wrptr = 0;
975
	card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
976 977
	card->evtbd_ring_size = 0;
	card->evtbd_ring_vbase = NULL;
978
	card->evtbd_ring_pbase = 0;
979 980 981 982 983 984 985 986 987 988 989 990 991 992 993

	return 0;
}

/*
 * This function allocates a buffer for CMDRSP
 */
static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;

	/* Allocate memory for receiving command response data */
	skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
	if (!skb) {
994 995
		mwifiex_dbg(adapter, ERROR,
			    "Unable to allocate skb for command response data.\n");
996 997 998
		return -ENOMEM;
	}
	skb_put(skb, MWIFIEX_UPLD_SIZE);
999 1000 1001
	if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
				   PCI_DMA_FROMDEVICE))
		return -1;
1002

1003
	card->cmdrsp_buf = skb;
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

	return 0;
}

/*
 * This function deletes a buffer for CMDRSP
 */
static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card;

	if (!adapter)
		return 0;

	card = adapter->card;

1020
	if (card && card->cmdrsp_buf) {
1021 1022
		mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
					 PCI_DMA_FROMDEVICE);
1023
		dev_kfree_skb_any(card->cmdrsp_buf);
1024
	}
1025

1026
	if (card && card->cmd_buf) {
1027 1028
		mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
					 PCI_DMA_TODEVICE);
1029
	}
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
	return 0;
}

/*
 * This function allocates a buffer for sleep cookie
 */
static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;

1040 1041 1042
	card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
						     &card->sleep_cookie_pbase);
	if (!card->sleep_cookie_vbase) {
1043 1044
		mwifiex_dbg(adapter, ERROR,
			    "pci_alloc_consistent failed!\n");
1045 1046 1047
		return -ENOMEM;
	}
	/* Init val of Sleep Cookie */
1048
	*(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
1049

1050 1051 1052
	mwifiex_dbg(adapter, INFO,
		    "alloc_scook: sleep cookie=0x%x\n",
		    *((u32 *)card->sleep_cookie_vbase));
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068

	return 0;
}

/*
 * This function deletes buffer for sleep cookie
 */
static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card;

	if (!adapter)
		return 0;

	card = adapter->card;

1069 1070 1071 1072 1073
	if (card && card->sleep_cookie_vbase) {
		pci_free_consistent(card->dev, sizeof(u32),
				    card->sleep_cookie_vbase,
				    card->sleep_cookie_pbase);
		card->sleep_cookie_vbase = NULL;
1074 1075 1076 1077 1078
	}

	return 0;
}

1079 1080 1081 1082 1083 1084 1085 1086
/* This function flushes the TX buffer descriptor ring
 * This function defined as handler is also called while cleaning TXRX
 * during disconnect/ bss stop.
 */
static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;

1087
	if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
1088 1089 1090 1091 1092 1093
		card->txbd_flush = 1;
		/* write pointer already set at last send
		 * send dnld-rdy intr again, wait for completion.
		 */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY)) {
1094 1095
			mwifiex_dbg(adapter, ERROR,
				    "failed to assert dnld-rdy interrupt.\n");
1096 1097 1098 1099 1100 1101
			return -1;
		}
	}
	return 0;
}

1102
/*
1103
 * This function unmaps and frees downloaded data buffer
1104
 */
1105
static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
1106
{
1107
	struct sk_buff *skb;
A
Avinash Patil 已提交
1108
	u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
1109
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
1110
	struct mwifiex_pfu_buf_desc *desc2;
1111
	struct pcie_service_card *card = adapter->card;
1112
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1113 1114 1115 1116 1117

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);

	/* Read the TX ring read pointer set by firmware */
1118
	if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
1119 1120
		mwifiex_dbg(adapter, ERROR,
			    "SEND COMP: failed to read reg->tx_rdptr\n");
1121 1122 1123
		return -1;
	}

1124 1125 1126
	mwifiex_dbg(adapter, DATA,
		    "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
		    card->txbd_rdptr, rdptr);
1127

A
Avinash Patil 已提交
1128
	num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
1129
	/* free from previous txbd_rdptr to current txbd_rdptr */
1130 1131 1132 1133
	while (((card->txbd_rdptr & reg->tx_mask) !=
		(rdptr & reg->tx_mask)) ||
	       ((card->txbd_rdptr & reg->tx_rollover_ind) !=
		(rdptr & reg->tx_rollover_ind))) {
A
Avinash Patil 已提交
1134 1135
		wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
			    reg->tx_start_ptr;
1136 1137

		skb = card->tx_buf_list[wrdoneidx];
1138

1139
		if (skb) {
1140 1141 1142
			mwifiex_dbg(adapter, DATA,
				    "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
				    skb, wrdoneidx);
1143 1144
			mwifiex_unmap_pci_memory(adapter, skb,
						 PCI_DMA_TODEVICE);
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155

			unmap_count++;

			if (card->txbd_flush)
				mwifiex_write_data_complete(adapter, skb, 0,
							    -1);
			else
				mwifiex_write_data_complete(adapter, skb, 0, 0);
		}

		card->tx_buf_list[wrdoneidx] = NULL;
A
Avinash Patil 已提交
1156 1157

		if (reg->pfu_enabled) {
1158
			desc2 = card->txbd_ring[wrdoneidx];
A
Avinash Patil 已提交
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
			memset(desc2, 0, sizeof(*desc2));
		} else {
			desc = card->txbd_ring[wrdoneidx];
			memset(desc, 0, sizeof(*desc));
		}
		switch (card->dev->device) {
		case PCIE_DEVICE_ID_MARVELL_88W8766P:
			card->txbd_rdptr++;
			break;
		case PCIE_DEVICE_ID_MARVELL_88W8897:
1169
		case PCIE_DEVICE_ID_MARVELL_88W8997:
A
Avinash Patil 已提交
1170 1171 1172 1173
			card->txbd_rdptr += reg->ring_tx_start_ptr;
			break;
		}

1174

1175
		if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
1176
			card->txbd_rdptr = ((card->txbd_rdptr &
1177 1178
					     reg->tx_rollover_ind) ^
					     reg->tx_rollover_ind);
1179 1180 1181 1182 1183 1184
	}

	if (unmap_count)
		adapter->data_sent = false;

	if (card->txbd_flush) {
1185
		if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
			card->txbd_flush = 0;
		else
			mwifiex_clean_pcie_ring_buf(adapter);
	}

	return 0;
}

/* This function sends data buffer to device. First 4 bytes of payload
 * are filled with payload length and payload type. Then this payload
 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
 * Download ready interrupt to FW is deffered if Tx ring is not full and
 * additional payload can be accomodated.
1199
 * Caller must ensure tx_param parameter to this function is not NULL.
1200 1201 1202 1203 1204 1205
 */
static int
mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
		       struct mwifiex_tx_param *tx_param)
{
	struct pcie_service_card *card = adapter->card;
1206
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
A
Avinash Patil 已提交
1207
	u32 wrindx, num_tx_buffs, rx_val;
1208 1209
	int ret;
	dma_addr_t buf_pa;
1210 1211
	struct mwifiex_pcie_buf_desc *desc = NULL;
	struct mwifiex_pfu_buf_desc *desc2 = NULL;
1212 1213 1214
	__le16 *tmp;

	if (!(skb->data && skb->len)) {
1215 1216 1217
		mwifiex_dbg(adapter, ERROR,
			    "%s(): invalid parameter <%p, %#x>\n",
			    __func__, skb->data, skb->len);
1218 1219 1220 1221 1222 1223
		return -1;
	}

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);

A
Avinash Patil 已提交
1224
	num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
1225 1226
	mwifiex_dbg(adapter, DATA,
		    "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1227 1228
		card->txbd_rdptr, card->txbd_wrptr);
	if (mwifiex_pcie_txbd_not_full(card)) {
1229 1230 1231
		u8 *payload;

		adapter->data_sent = true;
1232
		payload = skb->data;
1233 1234 1235 1236
		tmp = (__le16 *)&payload[0];
		*tmp = cpu_to_le16((u16)skb->len);
		tmp = (__le16 *)&payload[2];
		*tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
1237

1238
		if (mwifiex_map_pci_memory(adapter, skb, skb->len,
1239 1240 1241
					   PCI_DMA_TODEVICE))
			return -1;

A
Avinash Patil 已提交
1242
		wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
1243
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1244
		card->tx_buf_list[wrindx] = skb;
1245

A
Avinash Patil 已提交
1246
		if (reg->pfu_enabled) {
1247
			desc2 = card->txbd_ring[wrindx];
A
Avinash Patil 已提交
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
			desc2->paddr = buf_pa;
			desc2->len = (u16)skb->len;
			desc2->frag_len = (u16)skb->len;
			desc2->offset = 0;
			desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
					 MWIFIEX_BD_FLAG_LAST_DESC;
		} else {
			desc = card->txbd_ring[wrindx];
			desc->paddr = buf_pa;
			desc->len = (u16)skb->len;
			desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
				      MWIFIEX_BD_FLAG_LAST_DESC;
		}

		switch (card->dev->device) {
		case PCIE_DEVICE_ID_MARVELL_88W8766P:
			card->txbd_wrptr++;
			break;
		case PCIE_DEVICE_ID_MARVELL_88W8897:
1267
		case PCIE_DEVICE_ID_MARVELL_88W8997:
A
Avinash Patil 已提交
1268 1269 1270 1271 1272
			card->txbd_wrptr += reg->ring_tx_start_ptr;
			break;
		}

		if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
1273
			card->txbd_wrptr = ((card->txbd_wrptr &
1274 1275
						reg->tx_rollover_ind) ^
						reg->tx_rollover_ind);
1276

A
Avinash Patil 已提交
1277
		rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
1278 1279
		/* Write the TX ring write pointer in to reg->tx_wrptr */
		if (mwifiex_write_reg(adapter, reg->tx_wrptr,
A
Avinash Patil 已提交
1280
				      card->txbd_wrptr | rx_val)) {
1281 1282
			mwifiex_dbg(adapter, ERROR,
				    "SEND DATA: failed to write reg->tx_wrptr\n");
1283 1284
			ret = -1;
			goto done_unmap;
1285
		}
1286 1287 1288
		if ((mwifiex_pcie_txbd_not_full(card)) &&
		    tx_param->next_pkt_len) {
			/* have more packets and TxBD still can hold more */
1289 1290
			mwifiex_dbg(adapter, DATA,
				    "SEND DATA: delay dnld-rdy interrupt.\n");
1291 1292 1293 1294 1295
			adapter->data_sent = false;
		} else {
			/* Send the TX ready interrupt */
			if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
					      CPU_INTR_DNLD_RDY)) {
1296 1297
				mwifiex_dbg(adapter, ERROR,
					    "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1298 1299 1300
				ret = -1;
				goto done_unmap;
			}
1301
		}
1302 1303 1304 1305
		mwifiex_dbg(adapter, DATA,
			    "info: SEND DATA: Updated <Rd: %#x, Wr:\t"
			    "%#x> and sent packet to firmware successfully\n",
			    card->txbd_rdptr, card->txbd_wrptr);
1306
	} else {
1307 1308
		mwifiex_dbg(adapter, DATA,
			    "info: TX Ring full, can't send packets to fw\n");
1309 1310 1311 1312
		adapter->data_sent = true;
		/* Send the TX ready interrupt */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY))
1313 1314
			mwifiex_dbg(adapter, ERROR,
				    "SEND DATA: failed to assert door-bell intr\n");
1315 1316 1317
		return -EBUSY;
	}

1318 1319
	return -EINPROGRESS;
done_unmap:
1320
	mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1321
	card->tx_buf_list[wrindx] = NULL;
A
Avinash Patil 已提交
1322 1323 1324 1325 1326
	if (reg->pfu_enabled)
		memset(desc2, 0, sizeof(*desc2));
	else
		memset(desc, 0, sizeof(*desc));

1327
	return ret;
1328 1329 1330 1331 1332 1333 1334 1335 1336
}

/*
 * This function handles received buffer ring and
 * dispatches packets to upper
 */
static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
1337
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
A
Avinash Patil 已提交
1338
	u32 wrptr, rd_index, tx_val;
1339
	dma_addr_t buf_pa;
1340 1341
	int ret = 0;
	struct sk_buff *skb_tmp = NULL;
1342
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
1343
	struct mwifiex_pfu_buf_desc *desc2;
1344

1345 1346 1347
	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);

1348
	/* Read the RX ring Write pointer set by firmware */
1349
	if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
1350 1351
		mwifiex_dbg(adapter, ERROR,
			    "RECV DATA: failed to read reg->rx_wrptr\n");
1352 1353 1354
		ret = -1;
		goto done;
	}
1355
	card->rxbd_wrptr = wrptr;
1356

1357 1358 1359 1360
	while (((wrptr & reg->rx_mask) !=
		(card->rxbd_rdptr & reg->rx_mask)) ||
	       ((wrptr & reg->rx_rollover_ind) ==
		(card->rxbd_rdptr & reg->rx_rollover_ind))) {
1361 1362
		struct sk_buff *skb_data;
		u16 rx_len;
1363
		__le16 pkt_len;
1364

1365
		rd_index = card->rxbd_rdptr & reg->rx_mask;
1366 1367
		skb_data = card->rx_buf_list[rd_index];

1368 1369 1370 1371 1372 1373
		/* If skb allocation was failed earlier for Rx packet,
		 * rx_buf_list[rd_index] would have been left with a NULL.
		 */
		if (!skb_data)
			return -ENOMEM;

1374
		mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
1375 1376
		card->rx_buf_list[rd_index] = NULL;

1377
		/* Get data length from interface header -
1378 1379 1380 1381
		 * first 2 bytes for len, next 2 bytes is for type
		 */
		pkt_len = *((__le16 *)skb_data->data);
		rx_len = le16_to_cpu(pkt_len);
1382 1383
		if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
			    rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
1384 1385 1386
			mwifiex_dbg(adapter, ERROR,
				    "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
				    rx_len, card->rxbd_rdptr, wrptr);
1387 1388 1389
			dev_kfree_skb_any(skb_data);
		} else {
			skb_put(skb_data, rx_len);
1390 1391 1392
			mwifiex_dbg(adapter, DATA,
				    "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
				    card->rxbd_rdptr, wrptr, rx_len);
1393
			skb_pull(skb_data, INTF_HEADER_LEN);
1394 1395 1396 1397 1398 1399 1400
			if (adapter->rx_work_enabled) {
				skb_queue_tail(&adapter->rx_data_q, skb_data);
				adapter->data_received = true;
				atomic_inc(&adapter->rx_pending);
			} else {
				mwifiex_handle_rx_packet(adapter, skb_data);
			}
1401
		}
1402

1403
		skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1404
						      GFP_KERNEL);
1405
		if (!skb_tmp) {
1406 1407
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb.\n");
1408
			return -ENOMEM;
1409 1410
		}

1411 1412 1413 1414 1415
		if (mwifiex_map_pci_memory(adapter, skb_tmp,
					   MWIFIEX_RX_DATA_BUF_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;

1416
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
1417

1418 1419 1420
		mwifiex_dbg(adapter, INFO,
			    "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
			    skb_tmp, rd_index);
1421
		card->rx_buf_list[rd_index] = skb_tmp;
A
Avinash Patil 已提交
1422 1423

		if (reg->pfu_enabled) {
1424
			desc2 = card->rxbd_ring[rd_index];
A
Avinash Patil 已提交
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
			desc2->paddr = buf_pa;
			desc2->len = skb_tmp->len;
			desc2->frag_len = skb_tmp->len;
			desc2->offset = 0;
			desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
		} else {
			desc = card->rxbd_ring[rd_index];
			desc->paddr = buf_pa;
			desc->len = skb_tmp->len;
			desc->flags = 0;
		}
1436

1437
		if ((++card->rxbd_rdptr & reg->rx_mask) ==
1438 1439
							MWIFIEX_MAX_TXRX_BD) {
			card->rxbd_rdptr = ((card->rxbd_rdptr &
1440 1441
					     reg->rx_rollover_ind) ^
					     reg->rx_rollover_ind);
1442
		}
1443 1444 1445
		mwifiex_dbg(adapter, DATA,
			    "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
			    card->rxbd_rdptr, wrptr);
1446

A
Avinash Patil 已提交
1447
		tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
1448 1449
		/* Write the RX ring read pointer in to reg->rx_rdptr */
		if (mwifiex_write_reg(adapter, reg->rx_rdptr,
A
Avinash Patil 已提交
1450
				      card->rxbd_rdptr | tx_val)) {
1451 1452
			mwifiex_dbg(adapter, DATA,
				    "RECV DATA: failed to write reg->rx_rdptr\n");
1453 1454 1455 1456 1457
			ret = -1;
			goto done;
		}

		/* Read the RX ring Write pointer set by firmware */
1458
		if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
1459 1460
			mwifiex_dbg(adapter, ERROR,
				    "RECV DATA: failed to read reg->rx_wrptr\n");
1461 1462 1463
			ret = -1;
			goto done;
		}
1464 1465
		mwifiex_dbg(adapter, DATA,
			    "info: RECV DATA: Rcvd packet from fw successfully\n");
1466
		card->rxbd_wrptr = wrptr;
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
	}

done:
	return ret;
}

/*
 * This function downloads the boot command to device
 */
static int
mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
1479 1480
	dma_addr_t buf_pa;
	struct pcie_service_card *card = adapter->card;
1481
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1482

1483
	if (!(skb->data && skb->len)) {
1484 1485 1486
		mwifiex_dbg(adapter, ERROR,
			    "Invalid parameter in %s <%p. len %d>\n",
			    __func__, skb->data, skb->len);
1487 1488 1489
		return -1;
	}

1490
	if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1491 1492
		return -1;

1493
	buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1494

1495 1496 1497 1498
	/* Write the lower 32bits of the physical address to low command
	 * address scratch register
	 */
	if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
1499 1500 1501
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to write download command to boot code.\n",
			    __func__);
1502
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1503 1504 1505
		return -1;
	}

1506 1507 1508 1509
	/* Write the upper 32bits of the physical address to high command
	 * address scratch register
	 */
	if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
1510
			      (u32)((u64)buf_pa >> 32))) {
1511 1512 1513
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to write download command to boot code.\n",
			    __func__);
1514
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1515 1516 1517
		return -1;
	}

1518 1519
	/* Write the command length to cmd_size scratch register */
	if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
1520 1521 1522
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to write command len to cmd_size scratch reg\n",
			    __func__);
1523
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1524 1525 1526 1527 1528 1529
		return -1;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
1530 1531
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to assert door-bell intr\n", __func__);
1532
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1533 1534 1535 1536 1537 1538
		return -1;
	}

	return 0;
}

1539 1540 1541 1542 1543 1544
/* This function init rx port in firmware which in turn enables to receive data
 * from device before transmitting any packet.
 */
static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
1545
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
A
Avinash Patil 已提交
1546
	int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
1547

1548
	/* Write the RX ring read pointer in to reg->rx_rdptr */
A
Avinash Patil 已提交
1549 1550
	if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
			      tx_wrap)) {
1551 1552
		mwifiex_dbg(adapter, ERROR,
			    "RECV DATA: failed to write reg->rx_rdptr\n");
1553 1554 1555 1556 1557 1558
		return -1;
	}
	return 0;
}

/* This function downloads commands to the device
1559 1560 1561 1562 1563
 */
static int
mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
1564
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1565
	int ret = 0;
1566 1567
	dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
	u8 *payload = (u8 *)skb->data;
1568 1569

	if (!(skb->data && skb->len)) {
1570 1571 1572
		mwifiex_dbg(adapter, ERROR,
			    "Invalid parameter in %s <%p, %#x>\n",
			    __func__, skb->data, skb->len);
1573 1574 1575 1576 1577
		return -1;
	}

	/* Make sure a command response buffer is available */
	if (!card->cmdrsp_buf) {
1578 1579
		mwifiex_dbg(adapter, ERROR,
			    "No response buffer available, send command failed\n");
1580 1581 1582
		return -EBUSY;
	}

1583 1584
	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);
1585 1586

	adapter->cmd_sent = true;
1587 1588 1589 1590 1591 1592 1593 1594

	*(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
	*(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);

	if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
		return -1;

	card->cmd_buf = skb;
1595 1596 1597

	/* To send a command, the driver will:
		1. Write the 64bit physical address of the data buffer to
1598
		   cmd response address low  + cmd response address high
1599 1600 1601 1602 1603 1604 1605 1606
		2. Ring the door bell (i.e. set the door bell interrupt)

		In response to door bell interrupt, the firmware will perform
		the DMA of the command packet (first header to obtain the total
		length and then rest of the command).
	*/

	if (card->cmdrsp_buf) {
1607
		cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
1608 1609
		/* Write the lower 32bits of the cmdrsp buffer physical
		   address */
1610
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
1611
				      (u32)cmdrsp_buf_pa)) {
1612 1613
			mwifiex_dbg(adapter, ERROR,
				    "Failed to write download cmd to boot code.\n");
1614 1615 1616 1617 1618
			ret = -1;
			goto done;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
1619
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
1620
				      (u32)((u64)cmdrsp_buf_pa >> 32))) {
1621 1622
			mwifiex_dbg(adapter, ERROR,
				    "Failed to write download cmd to boot code.\n");
1623 1624 1625 1626 1627
			ret = -1;
			goto done;
		}
	}

1628
	cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
1629 1630 1631
	/* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
	if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
			      (u32)cmd_buf_pa)) {
1632 1633
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write download cmd to boot code.\n");
1634 1635 1636
		ret = -1;
		goto done;
	}
1637 1638
	/* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
	if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
1639
			      (u32)((u64)cmd_buf_pa >> 32))) {
1640 1641
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write download cmd to boot code.\n");
1642 1643 1644 1645
		ret = -1;
		goto done;
	}

1646 1647 1648
	/* Write the command length to reg->cmd_size */
	if (mwifiex_write_reg(adapter, reg->cmd_size,
			      card->cmd_buf->len)) {
1649 1650
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write cmd len to reg->cmd_size\n");
1651 1652 1653 1654 1655 1656 1657
		ret = -1;
		goto done;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
1658 1659
		mwifiex_dbg(adapter, ERROR,
			    "Failed to assert door-bell intr\n");
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676
		ret = -1;
		goto done;
	}

done:
	if (ret)
		adapter->cmd_sent = false;

	return 0;
}

/*
 * This function handles command complete interrupt
 */
static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
1677
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1678
	struct sk_buff *skb = card->cmdrsp_buf;
1679
	int count = 0;
1680 1681
	u16 rx_len;
	__le16 pkt_len;
1682

1683 1684
	mwifiex_dbg(adapter, CMD,
		    "info: Rx CMD Response\n");
1685

1686
	mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
1687

1688 1689 1690 1691 1692 1693 1694
	/* Unmap the command as a response has been received. */
	if (card->cmd_buf) {
		mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
					 PCI_DMA_TODEVICE);
		card->cmd_buf = NULL;
	}

1695 1696
	pkt_len = *((__le16 *)skb->data);
	rx_len = le16_to_cpu(pkt_len);
1697
	skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
1698 1699 1700
	skb_trim(skb, rx_len);
	skb_pull(skb, INTF_HEADER_LEN);

1701 1702
	if (!adapter->curr_cmd) {
		if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
1703 1704 1705
			if (mwifiex_write_reg(adapter,
					      PCIE_CPU_INT_EVENT,
					      CPU_INTR_SLEEP_CFM_DONE)) {
1706 1707
				mwifiex_dbg(adapter, ERROR,
					    "Write register failed\n");
1708 1709
				return -1;
			}
1710 1711
			mwifiex_delay_for_sleep_cookie(adapter,
						       MWIFIEX_MAX_DELAY_COUNT);
1712 1713
			while (reg->sleep_cookie && (count++ < 10) &&
			       mwifiex_pcie_ok_to_access_hw(adapter))
1714
				usleep_range(50, 60);
1715 1716 1717
			mwifiex_pcie_enable_host_int(adapter);
			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
							   skb->len);
1718
		} else {
1719 1720
			mwifiex_dbg(adapter, ERROR,
				    "There is no command but got cmdrsp\n");
1721
		}
1722 1723
		memcpy(adapter->upld_buf, skb->data,
		       min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
1724
		skb_push(skb, INTF_HEADER_LEN);
1725 1726 1727
		if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;
1728
	} else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1729
		adapter->curr_cmd->resp_skb = skb;
1730 1731 1732 1733 1734 1735 1736 1737
		adapter->cmd_resp_received = true;
		/* Take the pointer and set it to CMD node and will
		   return in the response complete callback */
		card->cmdrsp_buf = NULL;

		/* Clear the cmd-rsp buffer address in scratch registers. This
		   will prevent firmware from writing to the same response
		   buffer again. */
1738
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
1739 1740
			mwifiex_dbg(adapter, ERROR,
				    "cmd_done: failed to clear cmd_rsp_addr_lo\n");
1741 1742 1743 1744
			return -1;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
1745
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
1746 1747
			mwifiex_dbg(adapter, ERROR,
				    "cmd_done: failed to clear cmd_rsp_addr_hi\n");
1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765
			return -1;
		}
	}

	return 0;
}

/*
 * Command Response processing complete handler
 */
static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
					struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;

	if (skb) {
		card->cmdrsp_buf = skb;
		skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
1766 1767 1768 1769 1770
		if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;
	}

1771 1772 1773 1774 1775 1776 1777 1778 1779
	return 0;
}

/*
 * This function handles firmware event ready interrupt
 */
static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
1780
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1781 1782
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr, event;
1783
	struct mwifiex_evt_buf_desc *desc;
1784 1785 1786

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);
1787 1788

	if (adapter->event_received) {
1789 1790 1791
		mwifiex_dbg(adapter, EVENT,
			    "info: Event being processed,\t"
			    "do not process this interrupt just yet\n");
1792 1793 1794 1795
		return 0;
	}

	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1796 1797
		mwifiex_dbg(adapter, ERROR,
			    "info: Invalid read pointer...\n");
1798 1799 1800 1801
		return -1;
	}

	/* Read the event ring write pointer set by firmware */
1802
	if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
1803 1804
		mwifiex_dbg(adapter, ERROR,
			    "EventReady: failed to read reg->evt_wrptr\n");
1805 1806 1807
		return -1;
	}

1808 1809 1810
	mwifiex_dbg(adapter, EVENT,
		    "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
		    card->evtbd_rdptr, wrptr);
1811 1812
	if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
					      & MWIFIEX_EVTBD_MASK)) ||
1813 1814
	    ((wrptr & reg->evt_rollover_ind) ==
	     (card->evtbd_rdptr & reg->evt_rollover_ind))) {
1815 1816 1817 1818
		struct sk_buff *skb_cmd;
		__le16 data_len = 0;
		u16 evt_len;

1819 1820
		mwifiex_dbg(adapter, INFO,
			    "info: Read Index: %d\n", rdptr);
1821
		skb_cmd = card->evt_buf_list[rdptr];
1822
		mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
1823

1824 1825 1826
		/* Take the pointer and set it to event pointer in adapter
		   and will return back after event handling callback */
		card->evt_buf_list[rdptr] = NULL;
1827 1828
		desc = card->evtbd_ring[rdptr];
		memset(desc, 0, sizeof(*desc));
1829 1830 1831 1832 1833 1834 1835

		event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
		adapter->event_cause = event;
		/* The first 4bytes will be the event transfer header
		   len is 2 bytes followed by type which is 2 bytes */
		memcpy(&data_len, skb_cmd->data, sizeof(__le16));
		evt_len = le16_to_cpu(data_len);
1836
		skb_trim(skb_cmd, evt_len);
1837
		skb_pull(skb_cmd, INTF_HEADER_LEN);
1838 1839
		mwifiex_dbg(adapter, EVENT,
			    "info: Event length: %d\n", evt_len);
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852

		if ((evt_len > 0) && (evt_len  < MAX_EVENT_SIZE))
			memcpy(adapter->event_body, skb_cmd->data +
			       MWIFIEX_EVENT_HEADER_LEN, evt_len -
			       MWIFIEX_EVENT_HEADER_LEN);

		adapter->event_received = true;
		adapter->event_skb = skb_cmd;

		/* Do not update the event read pointer here, wait till the
		   buffer is released. This is just to make things simpler,
		   we need to find a better method of managing these buffers.
		*/
1853 1854 1855
	} else {
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_EVENT_DONE)) {
1856 1857
			mwifiex_dbg(adapter, ERROR,
				    "Write register failed\n");
1858 1859
			return -1;
		}
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871
	}

	return 0;
}

/*
 * Event processing complete handler
 */
static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
				       struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
1872
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1873 1874 1875
	int ret = 0;
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr;
1876
	struct mwifiex_evt_buf_desc *desc;
1877 1878 1879 1880

	if (!skb)
		return 0;

1881
	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1882 1883 1884
		mwifiex_dbg(adapter, ERROR,
			    "event_complete: Invalid rdptr 0x%x\n",
			    rdptr);
1885
		return -EINVAL;
1886
	}
1887 1888

	/* Read the event ring write pointer set by firmware */
1889
	if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
1890 1891
		mwifiex_dbg(adapter, ERROR,
			    "event_complete: failed to read reg->evt_wrptr\n");
1892
		return -1;
1893 1894 1895 1896
	}

	if (!card->evt_buf_list[rdptr]) {
		skb_push(skb, INTF_HEADER_LEN);
1897
		skb_put(skb, MAX_EVENT_SIZE - skb->len);
1898 1899 1900 1901
		if (mwifiex_map_pci_memory(adapter, skb,
					   MAX_EVENT_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;
1902
		card->evt_buf_list[rdptr] = skb;
1903
		desc = card->evtbd_ring[rdptr];
1904
		desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
1905 1906
		desc->len = (u16)skb->len;
		desc->flags = 0;
1907 1908
		skb = NULL;
	} else {
1909 1910 1911
		mwifiex_dbg(adapter, ERROR,
			    "info: ERROR: buf still valid at index %d, <%p, %p>\n",
			    rdptr, card->evt_buf_list[rdptr], skb);
1912 1913 1914 1915
	}

	if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
		card->evtbd_rdptr = ((card->evtbd_rdptr &
1916 1917
					reg->evt_rollover_ind) ^
					reg->evt_rollover_ind);
1918 1919
	}

1920 1921 1922
	mwifiex_dbg(adapter, EVENT,
		    "info: Updated <Rd: 0x%x, Wr: 0x%x>",
		    card->evtbd_rdptr, wrptr);
1923

1924 1925 1926
	/* Write the event ring read pointer in to reg->evt_rdptr */
	if (mwifiex_write_reg(adapter, reg->evt_rdptr,
			      card->evtbd_rdptr)) {
1927 1928
		mwifiex_dbg(adapter, ERROR,
			    "event_complete: failed to read reg->evt_rdptr\n");
1929
		return -1;
1930 1931
	}

1932 1933
	mwifiex_dbg(adapter, EVENT,
		    "info: Check Events Again\n");
1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
	ret = mwifiex_pcie_process_event_ready(adapter);

	return ret;
}

/*
 * This function downloads the firmware to the card.
 *
 * Firmware is downloaded to the card in blocks. Every block download
 * is tested for CRC errors, and retried a number of times before
 * returning failure.
 */
static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
				    struct mwifiex_fw_image *fw)
{
	int ret;
	u8 *firmware = fw->fw_buf;
	u32 firmware_len = fw->fw_len;
	u32 offset = 0;
	struct sk_buff *skb;
	u32 txlen, tx_blocks = 0, tries, len;
	u32 block_retry_cnt = 0;
1956
	struct pcie_service_card *card = adapter->card;
1957
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1958 1959

	if (!firmware || !firmware_len) {
1960 1961
		mwifiex_dbg(adapter, ERROR,
			    "No firmware image found! Terminating download\n");
1962 1963 1964
		return -1;
	}

1965 1966 1967
	mwifiex_dbg(adapter, INFO,
		    "info: Downloading FW image (%d bytes)\n",
		    firmware_len);
1968 1969

	if (mwifiex_pcie_disable_host_int(adapter)) {
1970 1971
		mwifiex_dbg(adapter, ERROR,
			    "%s: Disabling interrupts failed.\n", __func__);
1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
		return -1;
	}

	skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
	if (!skb) {
		ret = -ENOMEM;
		goto done;
	}

	/* Perform firmware data transfer */
	do {
		u32 ireg_intr = 0;

		/* More data? */
		if (offset >= firmware_len)
			break;

		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
1990
			ret = mwifiex_read_reg(adapter, reg->cmd_size,
1991 1992
					       &len);
			if (ret) {
1993 1994
				mwifiex_dbg(adapter, FATAL,
					    "Failed reading len from boot code\n");
1995 1996 1997 1998
				goto done;
			}
			if (len)
				break;
1999
			usleep_range(10, 20);
2000 2001 2002 2003 2004
		}

		if (!len) {
			break;
		} else if (len > MWIFIEX_UPLD_SIZE) {
2005 2006 2007
			mwifiex_dbg(adapter, ERROR,
				    "FW download failure @ %d, invalid length %d\n",
				    offset, len);
2008 2009 2010 2011 2012 2013 2014 2015 2016
			ret = -1;
			goto done;
		}

		txlen = len;

		if (len & BIT(0)) {
			block_retry_cnt++;
			if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
2017 2018 2019
				mwifiex_dbg(adapter, ERROR,
					    "FW download failure @ %d, over max\t"
					    "retry count\n", offset);
2020 2021 2022
				ret = -1;
				goto done;
			}
2023 2024 2025 2026
			mwifiex_dbg(adapter, ERROR,
				    "FW CRC error indicated by the\t"
				    "helper: len = 0x%04X, txlen = %d\n",
				    len, txlen);
2027 2028 2029 2030 2031 2032 2033 2034 2035 2036
			len &= ~BIT(0);
			/* Setting this to 0 to resend from same offset */
			txlen = 0;
		} else {
			block_retry_cnt = 0;
			/* Set blocksize to transfer - checking for
			   last block */
			if (firmware_len - offset < txlen)
				txlen = firmware_len - offset;

2037 2038
			tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
				    card->pcie.blksz_fw_dl;
2039 2040 2041 2042 2043 2044

			/* Copy payload to buffer */
			memmove(skb->data, &firmware[offset], txlen);
		}

		skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
2045
		skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
2046 2047 2048

		/* Send the boot command to device */
		if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
2049 2050
			mwifiex_dbg(adapter, ERROR,
				    "Failed to send firmware download command\n");
2051 2052 2053
			ret = -1;
			goto done;
		}
2054

2055 2056 2057 2058
		/* Wait for the command done interrupt */
		do {
			if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
					     &ireg_intr)) {
2059 2060 2061 2062
				mwifiex_dbg(adapter, ERROR,
					    "%s: Failed to read\t"
					    "interrupt status during fw dnld.\n",
					    __func__);
2063 2064
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_TODEVICE);
2065 2066 2067 2068 2069
				ret = -1;
				goto done;
			}
		} while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
			 CPU_INTR_DOOR_BELL);
2070

2071
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
2072

2073 2074 2075
		offset += txlen;
	} while (true);

2076 2077
	mwifiex_dbg(adapter, MSG,
		    "info: FW download over, size %d bytes\n", offset);
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092

	ret = 0;

done:
	dev_kfree_skb_any(skb);
	return ret;
}

/*
 * This function checks the firmware status in card.
 */
static int
mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
{
	int ret = 0;
2093
	u32 firmware_stat;
2094 2095
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2096 2097 2098 2099
	u32 tries;

	/* Mask spurios interrupts */
	if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
2100
			      HOST_INTR_MASK)) {
2101 2102
		mwifiex_dbg(adapter, ERROR,
			    "Write register failed\n");
2103 2104 2105
		return -1;
	}

2106 2107
	mwifiex_dbg(adapter, INFO,
		    "Setting driver ready signature\n");
2108 2109
	if (mwifiex_write_reg(adapter, reg->drv_rdy,
			      FIRMWARE_READY_PCIE)) {
2110 2111
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write driver ready signature\n");
2112 2113 2114 2115 2116
		return -1;
	}

	/* Wait for firmware initialization event */
	for (tries = 0; tries < poll_num; tries++) {
2117
		if (mwifiex_read_reg(adapter, reg->fw_status,
2118 2119 2120 2121
				     &firmware_stat))
			ret = -1;
		else
			ret = 0;
2122 2123 2124 2125

		mwifiex_dbg(adapter, INFO, "Try %d if FW is ready <%d,%#x>",
			    tries, ret, firmware_stat);

2126 2127 2128 2129 2130 2131
		if (ret)
			continue;
		if (firmware_stat == FIRMWARE_READY_PCIE) {
			ret = 0;
			break;
		} else {
2132
			msleep(100);
2133 2134 2135 2136
			ret = -1;
		}
	}

2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156
	return ret;
}

/* This function checks if WLAN is the winner.
 */
static int
mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
{
	u32 winner = 0;
	int ret = 0;
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

	if (mwifiex_read_reg(adapter, reg->fw_status, &winner)) {
		ret = -1;
	} else if (!winner) {
		mwifiex_dbg(adapter, INFO, "PCI-E is the winner\n");
		adapter->winner = 1;
	} else {
		mwifiex_dbg(adapter, ERROR,
2157
			    "PCI-E is not the winner <%#x>", winner);
2158 2159 2160 2161 2162 2163 2164 2165
	}

	return ret;
}

/*
 * This function reads the interrupt status from card.
 */
2166 2167
static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter,
				     int msg_id)
2168 2169 2170
{
	u32 pcie_ireg;
	unsigned long flags;
2171
	struct pcie_service_card *card = adapter->card;
2172

2173 2174 2175 2176 2177 2178 2179
	if (card->msi_enable) {
		spin_lock_irqsave(&adapter->int_lock, flags);
		adapter->int_status = 1;
		spin_unlock_irqrestore(&adapter->int_lock, flags);
		return;
	}

2180 2181 2182
	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		return;

2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193
	if (card->msix_enable && msg_id >= 0) {
		pcie_ireg = BIT(msg_id);
	} else {
		if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
				     &pcie_ireg)) {
			mwifiex_dbg(adapter, ERROR, "Read register failed\n");
			return;
		}

		if ((pcie_ireg == 0xFFFFFFFF) || !pcie_ireg)
			return;
2194 2195 2196 2197 2198 2199 2200


		mwifiex_pcie_disable_host_int(adapter);

		/* Clear the pending interrupts */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
				      ~pcie_ireg)) {
2201 2202
			mwifiex_dbg(adapter, ERROR,
				    "Write register failed\n");
2203 2204
			return;
		}
2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216
	}

	if (!adapter->pps_uapsd_mode &&
	    adapter->ps_state == PS_STATE_SLEEP &&
	    mwifiex_pcie_ok_to_access_hw(adapter)) {
		/* Potentially for PCIe we could get other
		 * interrupts like shared. Don't change power
		 * state until cookie is set
		 */
		adapter->ps_state = PS_STATE_AWAKE;
		adapter->pm_wakeup_fw_try = false;
		del_timer(&adapter->wakeup_timer);
2217
	}
2218 2219 2220 2221 2222

	spin_lock_irqsave(&adapter->int_lock, flags);
	adapter->int_status |= pcie_ireg;
	spin_unlock_irqrestore(&adapter->int_lock, flags);
	mwifiex_dbg(adapter, INTR, "ireg: 0x%08x\n", pcie_ireg);
2223 2224 2225 2226 2227 2228 2229 2230 2231 2232
}

/*
 * Interrupt handler for PCIe root port
 *
 * This function reads the interrupt status from firmware and assigns
 * the main process in workqueue which will handle the interrupt.
 */
static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
{
2233 2234
	struct mwifiex_msix_context *ctx = context;
	struct pci_dev *pdev = ctx->dev;
2235 2236 2237 2238
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;

	if (!pdev) {
2239
		pr_err("info: %s: pdev is NULL\n", __func__);
2240 2241 2242
		goto exit;
	}

2243
	card = pci_get_drvdata(pdev);
2244
	if (!card || !card->adapter) {
2245 2246
		pr_err("info: %s: card=%p adapter=%p\n", __func__, card,
		       card ? card->adapter : NULL);
2247 2248 2249 2250 2251 2252 2253
		goto exit;
	}
	adapter = card->adapter;

	if (adapter->surprise_removed)
		goto exit;

2254 2255 2256 2257 2258
	if (card->msix_enable)
		mwifiex_interrupt_status(adapter, ctx->msg_id);
	else
		mwifiex_interrupt_status(adapter, -1);

2259
	mwifiex_queue_main_work(adapter);
2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277

exit:
	return IRQ_HANDLED;
}

/*
 * This function checks the current interrupt status.
 *
 * The following interrupts are checked and handled by this function -
 *      - Data sent
 *      - Command sent
 *      - Command received
 *      - Packets received
 *      - Events received
 *
 * In case of Rx packets received, the packets are uploaded from card to
 * host and processed accordingly.
 */
2278
static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
2279 2280
{
	int ret;
2281
	u32 pcie_ireg = 0;
2282
	unsigned long flags;
2283
	struct pcie_service_card *card = adapter->card;
2284 2285

	spin_lock_irqsave(&adapter->int_lock, flags);
2286 2287 2288 2289
	if (!card->msi_enable) {
		/* Clear out unused interrupts */
		pcie_ireg = adapter->int_status;
	}
2290
	adapter->int_status = 0;
2291 2292
	spin_unlock_irqrestore(&adapter->int_lock, flags);

2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318
	if (card->msi_enable) {
		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
					     &pcie_ireg)) {
				mwifiex_dbg(adapter, ERROR,
					    "Read register failed\n");
				return -1;
			}

			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
				if (mwifiex_write_reg(adapter,
						      PCIE_HOST_INT_STATUS,
						      ~pcie_ireg)) {
					mwifiex_dbg(adapter, ERROR,
						    "Write register failed\n");
					return -1;
				}
				if (!adapter->pps_uapsd_mode &&
				    adapter->ps_state == PS_STATE_SLEEP) {
					adapter->ps_state = PS_STATE_AWAKE;
					adapter->pm_wakeup_fw_try = false;
					del_timer(&adapter->wakeup_timer);
				}
			}
		}
	}
2319 2320 2321
	while (pcie_ireg & HOST_INTR_MASK) {
		if (pcie_ireg & HOST_INTR_DNLD_DONE) {
			pcie_ireg &= ~HOST_INTR_DNLD_DONE;
2322 2323
			mwifiex_dbg(adapter, INTR,
				    "info: TX DNLD Done\n");
2324 2325 2326
			ret = mwifiex_pcie_send_data_complete(adapter);
			if (ret)
				return ret;
2327
		}
2328 2329
		if (pcie_ireg & HOST_INTR_UPLD_RDY) {
			pcie_ireg &= ~HOST_INTR_UPLD_RDY;
2330 2331
			mwifiex_dbg(adapter, INTR,
				    "info: Rx DATA\n");
2332 2333 2334 2335
			ret = mwifiex_pcie_process_recv_data(adapter);
			if (ret)
				return ret;
		}
2336 2337
		if (pcie_ireg & HOST_INTR_EVENT_RDY) {
			pcie_ireg &= ~HOST_INTR_EVENT_RDY;
2338 2339
			mwifiex_dbg(adapter, INTR,
				    "info: Rx EVENT\n");
2340 2341 2342 2343 2344
			ret = mwifiex_pcie_process_event_ready(adapter);
			if (ret)
				return ret;
		}

2345 2346
		if (pcie_ireg & HOST_INTR_CMD_DONE) {
			pcie_ireg &= ~HOST_INTR_CMD_DONE;
2347
			if (adapter->cmd_sent) {
2348 2349
				mwifiex_dbg(adapter, INTR,
					    "info: CMD sent Interrupt\n");
2350 2351 2352 2353 2354 2355
				adapter->cmd_sent = false;
			}
			/* Handle command response */
			ret = mwifiex_pcie_process_cmd_complete(adapter);
			if (ret)
				return ret;
2356 2357
			if (adapter->hs_activated)
				return ret;
2358 2359
		}

2360 2361 2362 2363 2364 2365
		if (card->msi_enable) {
			spin_lock_irqsave(&adapter->int_lock, flags);
			adapter->int_status = 0;
			spin_unlock_irqrestore(&adapter->int_lock, flags);
		}

2366 2367 2368
		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
					     &pcie_ireg)) {
2369 2370
				mwifiex_dbg(adapter, ERROR,
					    "Read register failed\n");
2371 2372 2373 2374 2375
				return -1;
			}

			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
				if (mwifiex_write_reg(adapter,
2376 2377
						      PCIE_HOST_INT_STATUS,
						      ~pcie_ireg)) {
2378 2379
					mwifiex_dbg(adapter, ERROR,
						    "Write register failed\n");
2380 2381 2382 2383 2384
					return -1;
				}
			}

		}
2385 2386 2387 2388 2389 2390
		if (!card->msi_enable) {
			spin_lock_irqsave(&adapter->int_lock, flags);
			pcie_ireg |= adapter->int_status;
			adapter->int_status = 0;
			spin_unlock_irqrestore(&adapter->int_lock, flags);
		}
2391
	}
2392 2393 2394
	mwifiex_dbg(adapter, INTR,
		    "info: cmd_sent=%d data_sent=%d\n",
		    adapter->cmd_sent, adapter->data_sent);
2395
	if (!card->msi_enable && adapter->ps_state != PS_STATE_SLEEP)
2396
		mwifiex_pcie_enable_host_int(adapter);
2397 2398 2399 2400

	return 0;
}

2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463
static int mwifiex_process_msix_int(struct mwifiex_adapter *adapter)
{
	int ret;
	u32 pcie_ireg;
	unsigned long flags;

	spin_lock_irqsave(&adapter->int_lock, flags);
	/* Clear out unused interrupts */
	pcie_ireg = adapter->int_status;
	adapter->int_status = 0;
	spin_unlock_irqrestore(&adapter->int_lock, flags);

	if (pcie_ireg & HOST_INTR_DNLD_DONE) {
		mwifiex_dbg(adapter, INTR,
			    "info: TX DNLD Done\n");
		ret = mwifiex_pcie_send_data_complete(adapter);
		if (ret)
			return ret;
	}
	if (pcie_ireg & HOST_INTR_UPLD_RDY) {
		mwifiex_dbg(adapter, INTR,
			    "info: Rx DATA\n");
		ret = mwifiex_pcie_process_recv_data(adapter);
		if (ret)
			return ret;
	}
	if (pcie_ireg & HOST_INTR_EVENT_RDY) {
		mwifiex_dbg(adapter, INTR,
			    "info: Rx EVENT\n");
		ret = mwifiex_pcie_process_event_ready(adapter);
		if (ret)
			return ret;
	}

	if (pcie_ireg & HOST_INTR_CMD_DONE) {
		if (adapter->cmd_sent) {
			mwifiex_dbg(adapter, INTR,
				    "info: CMD sent Interrupt\n");
			adapter->cmd_sent = false;
		}
		/* Handle command response */
		ret = mwifiex_pcie_process_cmd_complete(adapter);
		if (ret)
			return ret;
	}

	mwifiex_dbg(adapter, INTR,
		    "info: cmd_sent=%d data_sent=%d\n",
		    adapter->cmd_sent, adapter->data_sent);

	return 0;
}

static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;

	if (card->msix_enable)
		return mwifiex_process_msix_int(adapter);
	else
		return mwifiex_process_pcie_int(adapter);
}

2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477
/*
 * This function downloads data from driver to card.
 *
 * Both commands and data packets are transferred to the card by this
 * function.
 *
 * This function adds the PCIE specific header to the front of the buffer
 * before transferring. The header contains the length of the packet and
 * the type. The firmware handles the packets based upon this set type.
 */
static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
				     struct sk_buff *skb,
				     struct mwifiex_tx_param *tx_param)
{
2478
	if (!skb) {
2479 2480
		mwifiex_dbg(adapter, ERROR,
			    "Passed NULL skb to %s\n", __func__);
2481 2482 2483 2484
		return -1;
	}

	if (type == MWIFIEX_TYPE_DATA)
2485
		return mwifiex_pcie_send_data(adapter, skb, tx_param);
2486 2487 2488 2489 2490 2491
	else if (type == MWIFIEX_TYPE_CMD)
		return mwifiex_pcie_send_cmd(adapter, skb);

	return 0;
}

2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532
/* Function to dump PCIE scratch registers in case of FW crash
 */
static int
mwifiex_pcie_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
{
	char *p = drv_buf;
	char buf[256], *ptr;
	int i;
	u32 value;
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
	int pcie_scratch_reg[] = {PCIE_SCRATCH_12_REG,
				  PCIE_SCRATCH_13_REG,
				  PCIE_SCRATCH_14_REG};

	if (!p)
		return 0;

	mwifiex_dbg(adapter, MSG, "PCIE register dump start\n");

	if (mwifiex_read_reg(adapter, reg->fw_status, &value)) {
		mwifiex_dbg(adapter, ERROR, "failed to read firmware status");
		return 0;
	}

	ptr = buf;
	mwifiex_dbg(adapter, MSG, "pcie scratch register:");
	for (i = 0; i < ARRAY_SIZE(pcie_scratch_reg); i++) {
		mwifiex_read_reg(adapter, pcie_scratch_reg[i], &value);
		ptr += sprintf(ptr, "reg:0x%x, value=0x%x\n",
			       pcie_scratch_reg[i], value);
	}

	mwifiex_dbg(adapter, MSG, "%s\n", buf);
	p += sprintf(p, "%s\n", buf);

	mwifiex_dbg(adapter, MSG, "PCIE register dump end\n");

	return p - drv_buf;
}

2533 2534 2535 2536 2537 2538
/* This function read/write firmware */
static enum rdwr_status
mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
{
	int ret, tries;
	u8 ctrl_data;
2539
	u32 fw_status;
2540 2541 2542
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

2543 2544 2545
	if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status))
		return RDWR_STATUS_FAILURE;

2546 2547
	ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
				reg->fw_dump_host_ready);
2548
	if (ret) {
2549 2550
		mwifiex_dbg(adapter, ERROR,
			    "PCIE write err\n");
2551 2552 2553 2554 2555 2556 2557 2558 2559
		return RDWR_STATUS_FAILURE;
	}

	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
		mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
		if (ctrl_data == FW_DUMP_DONE)
			return RDWR_STATUS_SUCCESS;
		if (doneflag && ctrl_data == doneflag)
			return RDWR_STATUS_DONE;
2560
		if (ctrl_data != reg->fw_dump_host_ready) {
2561 2562
			mwifiex_dbg(adapter, WARN,
				    "The ctrl reg was changed, re-try again!\n");
2563
			ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2564
						reg->fw_dump_host_ready);
2565
			if (ret) {
2566 2567
				mwifiex_dbg(adapter, ERROR,
					    "PCIE write err\n");
2568 2569 2570 2571 2572 2573
				return RDWR_STATUS_FAILURE;
			}
		}
		usleep_range(100, 200);
	}

2574
	mwifiex_dbg(adapter, ERROR, "Fail to pull ctrl_data\n");
2575 2576 2577 2578
	return RDWR_STATUS_FAILURE;
}

/* This function dump firmware memory to file */
2579
static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2580 2581 2582 2583
{
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
	unsigned int reg, reg_start, reg_end;
2584
	u8 *dbg_ptr, *end_ptr, *tmp_ptr, fw_dump_num, dump_num;
2585
	u8 idx, i, read_reg, doneflag = 0;
2586 2587
	enum rdwr_status stat;
	u32 memory_size;
2588
	int ret;
2589

2590
	if (!card->pcie.can_dump_fw)
2591 2592
		return;

2593 2594 2595
	for (idx = 0; idx < adapter->num_mem_types; idx++) {
		struct memory_type_mapping *entry =
				&adapter->mem_type_mapping_tbl[idx];
2596 2597 2598 2599 2600 2601 2602 2603

		if (entry->mem_ptr) {
			vfree(entry->mem_ptr);
			entry->mem_ptr = NULL;
		}
		entry->mem_size = 0;
	}

2604
	mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n");
2605 2606 2607 2608

	/* Read the number of the memories which will dump */
	stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
	if (stat == RDWR_STATUS_FAILURE)
2609
		return;
2610 2611

	reg = creg->fw_dump_start;
2612 2613 2614 2615 2616 2617 2618
	mwifiex_read_reg_byte(adapter, reg, &fw_dump_num);

	/* W8997 chipset firmware dump will be restore in single region*/
	if (fw_dump_num == 0)
		dump_num = 1;
	else
		dump_num = fw_dump_num;
2619 2620 2621

	/* Read the length of every memory which will dump */
	for (idx = 0; idx < dump_num; idx++) {
2622 2623
		struct memory_type_mapping *entry =
				&adapter->mem_type_mapping_tbl[idx];
2624
		memory_size = 0;
2625 2626 2627 2628 2629 2630 2631 2632 2633
		if (fw_dump_num != 0) {
			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
			if (stat == RDWR_STATUS_FAILURE)
				return;

			reg = creg->fw_dump_start;
			for (i = 0; i < 4; i++) {
				mwifiex_read_reg_byte(adapter, reg, &read_reg);
				memory_size |= (read_reg << (i * 8));
2634
				reg++;
2635 2636 2637
			}
		} else {
			memory_size = MWIFIEX_FW_DUMP_MAX_MEMSIZE;
2638 2639 2640
		}

		if (memory_size == 0) {
2641
			mwifiex_dbg(adapter, MSG, "Firmware dump Finished!\n");
2642
			ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
2643
						creg->fw_dump_read_done);
2644
			if (ret) {
2645
				mwifiex_dbg(adapter, ERROR, "PCIE write err\n");
2646
				return;
2647
			}
2648 2649 2650
			break;
		}

2651 2652
		mwifiex_dbg(adapter, DUMP,
			    "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2653 2654 2655
		entry->mem_ptr = vmalloc(memory_size + 1);
		entry->mem_size = memory_size;
		if (!entry->mem_ptr) {
2656 2657
			mwifiex_dbg(adapter, ERROR,
				    "Vmalloc %s failed\n", entry->mem_name);
2658
			return;
2659 2660 2661 2662 2663
		}
		dbg_ptr = entry->mem_ptr;
		end_ptr = dbg_ptr + memory_size;

		doneflag = entry->done_flag;
2664 2665
		mwifiex_dbg(adapter, DUMP, "Start %s output, please wait...\n",
			    entry->mem_name);
2666 2667 2668 2669

		do {
			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
			if (RDWR_STATUS_FAILURE == stat)
2670
				return;
2671 2672 2673 2674 2675

			reg_start = creg->fw_dump_start;
			reg_end = creg->fw_dump_end;
			for (reg = reg_start; reg <= reg_end; reg++) {
				mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
2676
				if (dbg_ptr < end_ptr) {
2677
					dbg_ptr++;
2678
					continue;
2679
				}
2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692
				mwifiex_dbg(adapter, ERROR,
					    "pre-allocated buf not enough\n");
				tmp_ptr =
					vzalloc(memory_size + MWIFIEX_SIZE_4K);
				if (!tmp_ptr)
					return;
				memcpy(tmp_ptr, entry->mem_ptr, memory_size);
				vfree(entry->mem_ptr);
				entry->mem_ptr = tmp_ptr;
				tmp_ptr = NULL;
				dbg_ptr = entry->mem_ptr + memory_size;
				memory_size += MWIFIEX_SIZE_4K;
				end_ptr = entry->mem_ptr + memory_size;
2693 2694 2695 2696 2697
			}

			if (stat != RDWR_STATUS_DONE)
				continue;

2698 2699 2700
			mwifiex_dbg(adapter, DUMP,
				    "%s done: size=0x%tx\n",
				    entry->mem_name, dbg_ptr - entry->mem_ptr);
2701 2702 2703
			break;
		} while (true);
	}
2704
	mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n");
2705 2706
}

2707 2708 2709 2710
static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
{
	mwifiex_drv_info_dump(adapter);
	mwifiex_pcie_fw_dump(adapter);
2711
	mwifiex_upload_device_dump(adapter);
2712 2713
}

2714 2715
static unsigned long iface_work_flags;
static struct mwifiex_adapter *save_adapter;
2716 2717
static void mwifiex_pcie_work(struct work_struct *work)
{
2718
	if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
2719
			       &iface_work_flags))
2720
		mwifiex_pcie_device_dump_work(save_adapter);
2721 2722
}

2723
static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
2724
/* This function dumps FW information */
2725
static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
2726
{
2727
	save_adapter = adapter;
2728
	if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
2729 2730
		return;

2731
	set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
2732

2733
	schedule_work(&pcie_work);
2734 2735
}

2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750
/*
 * This function initializes the PCI-E host memory space, WCB rings, etc.
 *
 * The following initializations steps are followed -
 *      - Allocate TXBD ring buffers
 *      - Allocate RXBD ring buffers
 *      - Allocate event BD ring buffers
 *      - Allocate command response ring buffer
 *      - Allocate sleep cookie buffer
 */
static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int ret;
	struct pci_dev *pdev = card->dev;
2751
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2752 2753 2754 2755 2756 2757 2758 2759 2760

	pci_set_drvdata(pdev, card);

	ret = pci_enable_device(pdev);
	if (ret)
		goto err_enable_dev;

	pci_set_master(pdev);

X
Xinming Hu 已提交
2761
	pr_notice("try set_consistent_dma_mask(32)\n");
2762 2763
	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
X
Xinming Hu 已提交
2764
		pr_err("set_dma_mask(32) failed\n");
2765 2766 2767 2768 2769
		goto err_set_dma_mask;
	}

	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
X
Xinming Hu 已提交
2770
		pr_err("set_consistent_dma_mask(64) failed\n");
2771 2772 2773 2774 2775
		goto err_set_dma_mask;
	}

	ret = pci_request_region(pdev, 0, DRV_NAME);
	if (ret) {
X
Xinming Hu 已提交
2776
		pr_err("req_reg(0) error\n");
2777 2778 2779 2780
		goto err_req_region0;
	}
	card->pci_mmap = pci_iomap(pdev, 0, 0);
	if (!card->pci_mmap) {
X
Xinming Hu 已提交
2781
		pr_err("iomap(0) error\n");
2782
		ret = -EIO;
2783 2784 2785 2786
		goto err_iomap0;
	}
	ret = pci_request_region(pdev, 2, DRV_NAME);
	if (ret) {
X
Xinming Hu 已提交
2787
		pr_err("req_reg(2) error\n");
2788 2789 2790 2791
		goto err_req_region2;
	}
	card->pci_mmap1 = pci_iomap(pdev, 2, 0);
	if (!card->pci_mmap1) {
X
Xinming Hu 已提交
2792
		pr_err("iomap(2) error\n");
2793
		ret = -EIO;
2794 2795 2796
		goto err_iomap2;
	}

X
Xinming Hu 已提交
2797 2798
	pr_notice("PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
		  card->pci_mmap, card->pci_mmap1);
2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812

	card->cmdrsp_buf = NULL;
	ret = mwifiex_pcie_create_txbd_ring(adapter);
	if (ret)
		goto err_cre_txbd;
	ret = mwifiex_pcie_create_rxbd_ring(adapter);
	if (ret)
		goto err_cre_rxbd;
	ret = mwifiex_pcie_create_evtbd_ring(adapter);
	if (ret)
		goto err_cre_evtbd;
	ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
	if (ret)
		goto err_alloc_cmdbuf;
2813 2814 2815 2816 2817 2818 2819
	if (reg->sleep_cookie) {
		ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
		if (ret)
			goto err_alloc_cookie;
	} else {
		card->sleep_cookie_vbase = NULL;
	}
2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858
	return ret;

err_alloc_cookie:
	mwifiex_pcie_delete_cmdrsp_buf(adapter);
err_alloc_cmdbuf:
	mwifiex_pcie_delete_evtbd_ring(adapter);
err_cre_evtbd:
	mwifiex_pcie_delete_rxbd_ring(adapter);
err_cre_rxbd:
	mwifiex_pcie_delete_txbd_ring(adapter);
err_cre_txbd:
	pci_iounmap(pdev, card->pci_mmap1);
err_iomap2:
	pci_release_region(pdev, 2);
err_req_region2:
	pci_iounmap(pdev, card->pci_mmap);
err_iomap0:
	pci_release_region(pdev, 0);
err_req_region0:
err_set_dma_mask:
	pci_disable_device(pdev);
err_enable_dev:
	return ret;
}

/*
 * This function cleans up the allocated card buffers.
 *
 * The following are freed by this function -
 *      - TXBD ring buffers
 *      - RXBD ring buffers
 *      - Event BD ring buffers
 *      - Command response ring buffer
 *      - Sleep cookie buffer
 */
static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;
2859
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2860 2861

	if (user_rmmod) {
2862 2863
		mwifiex_dbg(adapter, INFO,
			    "Clearing driver ready signature\n");
2864
		if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
2865 2866
			mwifiex_dbg(adapter, ERROR,
				    "Failed to write driver not-ready signature\n");
2867 2868 2869 2870 2871
	}

	if (pdev) {
		pci_iounmap(pdev, card->pci_mmap);
		pci_iounmap(pdev, card->pci_mmap1);
2872
		pci_disable_device(pdev);
2873 2874
		pci_release_region(pdev, 2);
		pci_release_region(pdev, 0);
2875 2876 2877
	}
}

2878 2879
static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
{
2880
	int ret, i, j;
2881 2882 2883
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;

2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916
	if (card->pcie.reg->msix_support) {
		for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
			card->msix_entries[i].entry = i;
		ret = pci_enable_msix_exact(pdev, card->msix_entries,
					    MWIFIEX_NUM_MSIX_VECTORS);
		if (!ret) {
			for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++) {
				card->msix_ctx[i].dev = pdev;
				card->msix_ctx[i].msg_id = i;

				ret = request_irq(card->msix_entries[i].vector,
						  mwifiex_pcie_interrupt, 0,
						  "MWIFIEX_PCIE_MSIX",
						  &card->msix_ctx[i]);
				if (ret)
					break;
			}

			if (ret) {
				mwifiex_dbg(adapter, INFO, "request_irq fail: %d\n",
					    ret);
				for (j = 0; j < i; j++)
					free_irq(card->msix_entries[j].vector,
						 &card->msix_ctx[i]);
				pci_disable_msix(pdev);
			} else {
				mwifiex_dbg(adapter, MSG, "MSIx enabled!");
				card->msix_enable = 1;
				return 0;
			}
		}
	}

2917 2918 2919 2920 2921 2922 2923
	if (pci_enable_msi(pdev) != 0)
		pci_disable_msi(pdev);
	else
		card->msi_enable = 1;

	mwifiex_dbg(adapter, INFO, "msi_enable = %d\n", card->msi_enable);

2924 2925
	card->share_irq_ctx.dev = pdev;
	card->share_irq_ctx.msg_id = -1;
2926
	ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2927
			  "MRVL_PCIE", &card->share_irq_ctx);
2928 2929 2930 2931 2932 2933 2934 2935
	if (ret) {
		pr_err("request_irq failed: ret=%d\n", ret);
		return -1;
	}

	return 0;
}

2936
/*
J
Julia Lawall 已提交
2937
 * This function gets the firmware name for downloading by revision id
2938 2939 2940 2941 2942 2943
 *
 * Read revision id register to get revision id
 */
static void mwifiex_pcie_get_fw_name(struct mwifiex_adapter *adapter)
{
	int revision_id = 0;
2944
	int version, magic;
2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962
	struct pcie_service_card *card = adapter->card;

	switch (card->dev->device) {
	case PCIE_DEVICE_ID_MARVELL_88W8766P:
		strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME);
		break;
	case PCIE_DEVICE_ID_MARVELL_88W8897:
		mwifiex_write_reg(adapter, 0x0c58, 0x80c00000);
		mwifiex_read_reg(adapter, 0x0c58, &revision_id);
		revision_id &= 0xff00;
		switch (revision_id) {
		case PCIE8897_A0:
			strcpy(adapter->fw_name, PCIE8897_A0_FW_NAME);
			break;
		case PCIE8897_B0:
			strcpy(adapter->fw_name, PCIE8897_B0_FW_NAME);
			break;
		default:
2963 2964
			strcpy(adapter->fw_name, PCIE8897_DEFAULT_FW_NAME);

2965 2966
			break;
		}
2967
		break;
2968
	case PCIE_DEVICE_ID_MARVELL_88W8997:
2969
		mwifiex_read_reg(adapter, 0x8, &revision_id);
2970
		mwifiex_read_reg(adapter, 0x0cd0, &version);
2971 2972
		mwifiex_read_reg(adapter, 0x0cd4, &magic);
		revision_id &= 0xff;
2973
		version &= 0x7;
2974 2975 2976 2977 2978 2979 2980 2981
		magic &= 0xff;
		if (revision_id == PCIE8997_A1 &&
		    magic == CHIP_MAGIC_VALUE &&
		    version == CHIP_VER_PCIEUART)
			strcpy(adapter->fw_name, PCIEUART8997_FW_NAME_V4);
		else
			strcpy(adapter->fw_name, PCIEUSB8997_FW_NAME_V4);
		break;
2982 2983 2984 2985 2986
	default:
		break;
	}
}

2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998
/*
 * This function registers the PCIE device.
 *
 * PCIE IRQ is claimed, block size is set and driver data is initialized.
 */
static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;

	/* save adapter pointer in card */
	card->adapter = adapter;

2999
	if (mwifiex_pcie_request_irq(adapter))
3000 3001
		return -1;

3002
	adapter->tx_buf_size = card->pcie.tx_buf_size;
3003 3004
	adapter->mem_type_mapping_tbl = card->pcie.mem_type_mapping_tbl;
	adapter->num_mem_types = card->pcie.num_mem_types;
3005
	adapter->ext_scan = card->pcie.can_ext_scan;
3006
	mwifiex_pcie_get_fw_name(adapter);
3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019

	return 0;
}

/*
 * This function unregisters the PCIE device.
 *
 * The PCIE IRQ is released, the function is disabled and driver
 * data is set to null.
 */
static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
3020
	struct pci_dev *pdev;
3021
	int i;
3022 3023

	if (card) {
3024
		pdev = card->dev;
3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042
		if (card->msix_enable) {
			for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
				synchronize_irq(card->msix_entries[i].vector);

			for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
				free_irq(card->msix_entries[i].vector,
					 &card->msix_ctx[i]);

			card->msix_enable = 0;
			pci_disable_msix(pdev);
	       } else {
			mwifiex_dbg(adapter, INFO,
				    "%s(): calling free_irq()\n", __func__);
		       free_irq(card->dev->irq, &card->share_irq_ctx);

			if (card->msi_enable)
				pci_disable_msi(pdev);
	       }
3043 3044
	}
}
3045

3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126
/* This function initializes the PCI-E host memory space, WCB rings, etc.
 *
 * The following initializations steps are followed -
 *      - Allocate TXBD ring buffers
 *      - Allocate RXBD ring buffers
 *      - Allocate event BD ring buffers
 *      - Allocate command response ring buffer
 *      - Allocate sleep cookie buffer
 * Part of mwifiex_pcie_init(), not reset the PCIE registers
 */
static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int ret;
	struct pci_dev *pdev = card->dev;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

	card->cmdrsp_buf = NULL;
	ret = mwifiex_pcie_create_txbd_ring(adapter);
	if (ret) {
		mwifiex_dbg(adapter, ERROR, "Failed to create txbd ring\n");
		goto err_cre_txbd;
	}

	ret = mwifiex_pcie_create_rxbd_ring(adapter);
	if (ret) {
		mwifiex_dbg(adapter, ERROR, "Failed to create rxbd ring\n");
		goto err_cre_rxbd;
	}

	ret = mwifiex_pcie_create_evtbd_ring(adapter);
	if (ret) {
		mwifiex_dbg(adapter, ERROR, "Failed to create evtbd ring\n");
		goto err_cre_evtbd;
	}

	ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
	if (ret) {
		mwifiex_dbg(adapter, ERROR, "Failed to allocate cmdbuf buffer\n");
		goto err_alloc_cmdbuf;
	}

	if (reg->sleep_cookie) {
		ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
		if (ret) {
			mwifiex_dbg(adapter, ERROR, "Failed to allocate sleep_cookie buffer\n");
			goto err_alloc_cookie;
		}
	} else {
		card->sleep_cookie_vbase = NULL;
	}
	return;

err_alloc_cookie:
	mwifiex_pcie_delete_cmdrsp_buf(adapter);
err_alloc_cmdbuf:
	mwifiex_pcie_delete_evtbd_ring(adapter);
err_cre_evtbd:
	mwifiex_pcie_delete_rxbd_ring(adapter);
err_cre_rxbd:
	mwifiex_pcie_delete_txbd_ring(adapter);
err_cre_txbd:
	pci_iounmap(pdev, card->pci_mmap1);
}

/* This function cleans up the PCI-E host memory space.
 * Some code is extracted from mwifiex_unregister_dev()
 *
 */
static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

	if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
		mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n");

	adapter->seq_num = 0;
	adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;

	if (card) {
3127 3128 3129
		if (reg->sleep_cookie)
			mwifiex_pcie_delete_sleep_cookie_buf(adapter);

3130 3131 3132 3133 3134
		mwifiex_pcie_delete_cmdrsp_buf(adapter);
		mwifiex_pcie_delete_evtbd_ring(adapter);
		mwifiex_pcie_delete_rxbd_ring(adapter);
		mwifiex_pcie_delete_txbd_ring(adapter);
		card->cmdrsp_buf = NULL;
3135
	}
3136 3137

	return;
3138 3139 3140 3141 3142 3143
}

static struct mwifiex_if_ops pcie_ops = {
	.init_if =			mwifiex_pcie_init,
	.cleanup_if =			mwifiex_pcie_cleanup,
	.check_fw_status =		mwifiex_check_fw_status,
3144
	.check_winner_status =          mwifiex_check_winner_status,
3145 3146 3147 3148
	.prog_fw =			mwifiex_prog_fw_w_helper,
	.register_dev =			mwifiex_register_dev,
	.unregister_dev =		mwifiex_unregister_dev,
	.enable_int =			mwifiex_pcie_enable_host_int,
3149
	.disable_int =			mwifiex_pcie_disable_host_int_noerr,
3150 3151 3152 3153 3154 3155 3156 3157 3158 3159
	.process_int_status =		mwifiex_process_int_status,
	.host_to_card =			mwifiex_pcie_host_to_card,
	.wakeup =			mwifiex_pm_wakeup_card,
	.wakeup_complete =		mwifiex_pm_wakeup_card_complete,

	/* PCIE specific */
	.cmdrsp_complete =		mwifiex_pcie_cmdrsp_complete,
	.event_complete =		mwifiex_pcie_event_complete,
	.update_mp_end_port =		NULL,
	.cleanup_mpa_buf =		NULL,
3160
	.init_fw_port =			mwifiex_pcie_init_fw_port,
3161
	.clean_pcie_ring =		mwifiex_clean_pcie_ring_buf,
3162
	.reg_dump =			mwifiex_pcie_reg_dump,
3163
	.device_dump =			mwifiex_pcie_device_dump,
3164 3165
	.down_dev =			mwifiex_pcie_down_dev,
	.up_dev =			mwifiex_pcie_up_dev,
3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177
};

/*
 * This function initializes the PCIE driver module.
 *
 * This initiates the semaphore and registers the device with
 * PCIE bus.
 */
static int mwifiex_pcie_init_module(void)
{
	int ret;

A
Avinash Patil 已提交
3178
	pr_debug("Marvell PCIe Driver\n");
3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210

	sema_init(&add_remove_card_sem, 1);

	/* Clear the flag in case user removes the card. */
	user_rmmod = 0;

	ret = pci_register_driver(&mwifiex_pcie);
	if (ret)
		pr_err("Driver register failed!\n");
	else
		pr_debug("info: Driver registered successfully!\n");

	return ret;
}

/*
 * This function cleans up the PCIE driver.
 *
 * The following major steps are followed for cleanup -
 *      - Resume the device if its suspended
 *      - Disconnect the device if connected
 *      - Shutdown the firmware
 *      - Unregister the device from PCIE bus.
 */
static void mwifiex_pcie_cleanup_module(void)
{
	if (!down_interruptible(&add_remove_card_sem))
		up(&add_remove_card_sem);

	/* Set the flag as user is removing this module. */
	user_rmmod = 1;

3211
	cancel_work_sync(&pcie_work);
3212 3213 3214 3215 3216 3217 3218 3219 3220 3221
	pci_unregister_driver(&mwifiex_pcie);
}

module_init(mwifiex_pcie_init_module);
module_exit(mwifiex_pcie_cleanup_module);

MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
MODULE_VERSION(PCIE_VERSION);
MODULE_LICENSE("GPL v2");