pcie.c 75.8 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
static struct memory_type_mapping mem_type_mapping_tbl[] = {
	{"ITCM", NULL, 0, 0xF0},
	{"DTCM", NULL, 0, 0xF1},
	{"SQRAM", NULL, 0, 0xF2},
	{"IRAM", NULL, 0, 0xF3},
45 46 47 48
	{"APU", NULL, 0, 0xF4},
	{"CIU", NULL, 0, 0xF5},
	{"ICU", NULL, 0, 0xF6},
	{"MAC", NULL, 0, 0xF7},
49 50
};

51 52
static int
mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
53
		       size_t size, int flags)
54
{
55
	struct pcie_service_card *card = adapter->card;
56
	struct mwifiex_dma_mapping mapping;
57

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

68 69 70 71 72 73
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;

74
	mwifiex_get_mapping(skb, &mapping);
75 76 77
	pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
}

78 79 80 81 82 83 84
/*
 * 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;
85 86 87 88
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

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

90 91
	if (card->sleep_cookie_vbase) {
		cookie_addr = (u32 *)card->sleep_cookie_vbase;
92 93 94
		mwifiex_dbg(adapter, INFO,
			    "info: ACCESS_HW: sleep cookie=0x%x\n",
			    *cookie_addr);
95 96 97 98 99 100 101
		if (*cookie_addr == FW_AWAKE_COOKIE)
			return true;
	}

	return false;
}

102
#ifdef CONFIG_PM_SLEEP
103 104 105 106 107 108 109 110
/*
 * 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.
 */
111
static int mwifiex_pcie_suspend(struct device *dev)
112 113 114 115
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
	int hs_actived;
116
	struct pci_dev *pdev = to_pci_dev(dev);
117 118

	if (pdev) {
119
		card = pci_get_drvdata(pdev);
120 121 122 123 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;

	hs_actived = mwifiex_enable_hs(adapter);

	/* Indicate device suspended */
	adapter->is_suspended = true;
135
	adapter->hs_enabling = false;
136 137 138 139 140 141 142 143 144 145 146 147

	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.
 */
148
static int mwifiex_pcie_resume(struct device *dev)
149 150 151
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
152
	struct pci_dev *pdev = to_pci_dev(dev);
153 154

	if (pdev) {
155
		card = pci_get_drvdata(pdev);
156 157 158 159 160 161 162 163 164 165 166 167
		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) {
168 169
		mwifiex_dbg(adapter, WARN,
			    "Device already resumed\n");
170 171 172 173 174 175 176 177 178 179
		return 0;
	}

	adapter->is_suspended = false;

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

	return 0;
}
180
#endif
181

182 183 184 185 186 187 188 189 190 191 192 193
/*
 * 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;

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

	card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
197
	if (!card)
198 199 200 201
		return -ENOMEM;

	card->dev = pdev;

202 203 204 205 206
	if (ent->driver_data) {
		struct mwifiex_pcie_device *data = (void *)ent->driver_data;
		card->pcie.firmware = data->firmware;
		card->pcie.reg = data->reg;
		card->pcie.blksz_fw_dl = data->blksz_fw_dl;
207
		card->pcie.tx_buf_size = data->tx_buf_size;
208
		card->pcie.can_dump_fw = data->can_dump_fw;
209
		card->pcie.can_ext_scan = data->can_ext_scan;
210 211
	}

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
	if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
			     MWIFIEX_PCIE)) {
		pr_err("%s failed\n", __func__);
		kfree(card);
		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;
229
	struct mwifiex_private *priv;
230 231 232 233 234 235 236 237 238 239

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

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

	if (user_rmmod) {
240
#ifdef CONFIG_PM_SLEEP
241
		if (adapter->is_suspended)
242
			mwifiex_pcie_resume(&pdev->dev);
243 244
#endif

245
		mwifiex_deauthenticate_all(adapter);
246

247
		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
248

249 250 251
		mwifiex_disable_auto_ds(priv);

		mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
252 253 254 255 256
	}

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

257 258 259 260 261 262 263 264
static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
{
	user_rmmod = 1;
	mwifiex_pcie_remove(pdev);

	return;
}

265
static const struct pci_device_id mwifiex_ids[] = {
266 267 268
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
269
		.driver_data = (unsigned long)&mwifiex_pcie8766,
270
	},
A
Avinash Patil 已提交
271 272 273
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
274 275 276 277 278 279
		.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 已提交
280
	},
281 282 283 284 285
	{},
};

MODULE_DEVICE_TABLE(pci, mwifiex_ids);

286 287 288 289 290 291
#ifdef CONFIG_PM_SLEEP
/* Power Management Hooks */
static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
				mwifiex_pcie_resume);
#endif

292 293 294 295 296 297
/* 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,
298 299 300 301
#ifdef CONFIG_PM_SLEEP
	.driver   = {
		.pm = &mwifiex_pcie_pm_ops,
	},
302
#endif
303
	.shutdown = mwifiex_pcie_shutdown,
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
};

/*
 * 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);
326 327
	if (*data == 0xffffffff)
		return 0xffffffff;
328 329 330 331

	return 0;
}

332 333 334 335 336 337 338 339 340 341 342
/* 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;
}

343
/*
344
 * This function adds delay loop to ensure FW is awake before proceeding.
345
 */
346
static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
347 348 349
{
	int i = 0;

350
	while (mwifiex_pcie_ok_to_access_hw(adapter)) {
351
		i++;
352
		usleep_range(10, 20);
353
		/* 50ms max wait */
354
		if (i == 5000)
355 356 357
			break;
	}

358 359 360
	return;
}

361 362 363 364 365 366 367 368 369 370 371 372
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) {
373 374
			mwifiex_dbg(adapter, INFO,
				    "sleep cookie found at count %d\n", count);
375 376 377 378 379 380
			break;
		}
		usleep_range(20, 30);
	}

	if (count >= max_delay_loop_cnt)
381 382
		mwifiex_dbg(adapter, INFO,
			    "max count reached while accessing sleep cookie\n");
383 384
}

385 386 387 388 389 390 391
/* 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;

392 393
	mwifiex_dbg(adapter, EVENT,
		    "event: Wakeup device...\n");
394

395 396 397 398 399
	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)) {
400 401
		mwifiex_dbg(adapter, ERROR,
			    "Reading fw_status register failed\n");
402 403 404
		return -1;
	}

405 406
	if (reg->sleep_cookie) {
		mwifiex_pcie_dev_wakeup_delay(adapter);
407 408
		mwifiex_dbg(adapter, INFO,
			    "PCIE wakeup: Setting PS_STATE_AWAKE\n");
409 410
		adapter->ps_state = PS_STATE_AWAKE;
	}
411 412 413 414 415 416 417 418 419 420 421

	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)
{
422 423
	mwifiex_dbg(adapter, CMD,
		    "cmd: Wakeup device completed\n");
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438

	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)) {
439 440
			mwifiex_dbg(adapter, ERROR,
				    "Disable host interrupt failed\n");
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
			return -1;
		}
	}

	return 0;
}

/*
 * 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)) {
460 461
			mwifiex_dbg(adapter, ERROR,
				    "Enable host interrupt failed\n");
462 463 464 465 466 467 468 469
			return -1;
		}
	}

	return 0;
}

/*
470 471 472 473 474
 * 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 已提交
475
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
476
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
477
	struct mwifiex_pfu_buf_desc *desc2;
478 479 480 481
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		card->tx_buf_list[i] = NULL;
A
Avinash Patil 已提交
482 483 484 485 486 487 488 489 490 491 492
		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));
		}
493 494 495 496 497 498 499 500 501 502 503 504
	}

	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 已提交
505
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
506 507
	struct sk_buff *skb;
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
508
	struct mwifiex_pfu_buf_desc *desc2;
509 510 511 512 513
	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 */
514 515
		skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
						  GFP_KERNEL | GFP_DMA);
516
		if (!skb) {
517 518
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb for RX ring.\n");
519 520 521 522 523 524 525 526 527
			kfree(card->rxbd_ring_vbase);
			return -ENOMEM;
		}

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

528
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
529

530 531 532 533
		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));
534 535

		card->rx_buf_list[i] = skb;
A
Avinash Patil 已提交
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
		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;
		}
553 554 555 556 557 558 559 560 561 562 563 564
	}

	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;
565
	struct mwifiex_evt_buf_desc *desc;
566 567 568 569 570 571 572 573
	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) {
574 575
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb for EVENT buf.\n");
576 577 578 579 580 581 582 583 584
			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;

585
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
586

587 588 589 590
		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));
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609

		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 已提交
610
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
611 612
	struct sk_buff *skb;
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
613
	struct mwifiex_pfu_buf_desc *desc2;
614 615 616
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
A
Avinash Patil 已提交
617 618 619 620
		if (reg->pfu_enabled) {
			desc2 = card->txbd_ring[i];
			if (card->tx_buf_list[i]) {
				skb = card->tx_buf_list[i];
621 622
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_TODEVICE);
A
Avinash Patil 已提交
623 624 625 626 627 628 629
				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];
630 631
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_TODEVICE);
A
Avinash Patil 已提交
632 633 634
				dev_kfree_skb_any(skb);
			}
			memset(desc, 0, sizeof(*desc));
635 636 637 638 639 640 641 642 643 644 645 646 647
		}
		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 已提交
648
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
649
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
650
	struct mwifiex_pfu_buf_desc *desc2;
651 652 653 654
	struct sk_buff *skb;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
A
Avinash Patil 已提交
655 656 657 658
		if (reg->pfu_enabled) {
			desc2 = card->rxbd_ring[i];
			if (card->rx_buf_list[i]) {
				skb = card->rx_buf_list[i];
659 660
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_FROMDEVICE);
A
Avinash Patil 已提交
661 662 663 664 665 666 667
				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];
668 669
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_FROMDEVICE);
A
Avinash Patil 已提交
670 671 672
				dev_kfree_skb_any(skb);
			}
			memset(desc, 0, sizeof(*desc));
673
		}
A
Avinash Patil 已提交
674
		card->rx_buf_list[i] = NULL;
675 676 677 678 679 680 681 682 683 684 685
	}

	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;
686
	struct mwifiex_evt_buf_desc *desc;
687 688 689 690 691 692 693
	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];
694 695
			mwifiex_unmap_pci_memory(adapter, skb,
						 PCI_DMA_FROMDEVICE);
696 697 698 699 700 701 702 703 704 705
			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
706 707 708 709
 */
static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
710
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
711 712 713 714 715 716 717

	/*
	 * 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 已提交
718 719 720 721 722

	if (reg->pfu_enabled)
		card->txbd_rdptr = 0;
	else
		card->txbd_rdptr |= reg->tx_rollover_ind;
723 724 725

	/* allocate shared memory for the BD ring and divide the same in to
	   several descriptors */
A
Avinash Patil 已提交
726 727 728 729 730 731 732
	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;

733 734 735
	mwifiex_dbg(adapter, INFO,
		    "info: txbd_ring: Allocating %d bytes\n",
		    card->txbd_ring_size);
736 737 738
	card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
						     card->txbd_ring_size,
						     &card->txbd_ring_pbase);
739
	if (!card->txbd_ring_vbase) {
740 741 742
		mwifiex_dbg(adapter, ERROR,
			    "allocate consistent memory (%d bytes) failed!\n",
			    card->txbd_ring_size);
743
		return -ENOMEM;
744
	}
745 746 747 748 749
	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);
750

751
	return mwifiex_init_txq_ring(adapter);
752 753 754 755 756
}

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

759
	mwifiex_cleanup_txq_ring(adapter);
760

761 762 763 764
	if (card->txbd_ring_vbase)
		pci_free_consistent(card->dev, card->txbd_ring_size,
				    card->txbd_ring_vbase,
				    card->txbd_ring_pbase);
765 766
	card->txbd_ring_size = 0;
	card->txbd_wrptr = 0;
767
	card->txbd_rdptr = 0 | reg->tx_rollover_ind;
768
	card->txbd_ring_vbase = NULL;
769
	card->txbd_ring_pbase = 0;
770 771 772 773 774 775 776 777 778 779

	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;
780
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
781 782 783 784 785 786 787

	/*
	 * 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;
788
	card->rxbd_rdptr = reg->rx_rollover_ind;
789

A
Avinash Patil 已提交
790 791 792 793 794 795 796
	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;

797 798 799
	mwifiex_dbg(adapter, INFO,
		    "info: rxbd_ring: Allocating %d bytes\n",
		    card->rxbd_ring_size);
800 801 802
	card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
						     card->rxbd_ring_size,
						     &card->rxbd_ring_pbase);
803
	if (!card->rxbd_ring_vbase) {
804 805 806
		mwifiex_dbg(adapter, ERROR,
			    "allocate consistent memory (%d bytes) failed!\n",
			    card->rxbd_ring_size);
807
		return -ENOMEM;
808 809
	}

810 811 812 813 814
	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);
815

816
	return mwifiex_init_rxq_ring(adapter);
817 818 819 820 821 822 823 824
}

/*
 * 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;
825
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
826

827
	mwifiex_cleanup_rxq_ring(adapter);
828

829 830 831 832
	if (card->rxbd_ring_vbase)
		pci_free_consistent(card->dev, card->rxbd_ring_size,
				    card->rxbd_ring_vbase,
				    card->rxbd_ring_pbase);
833 834
	card->rxbd_ring_size = 0;
	card->rxbd_wrptr = 0;
835
	card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
836
	card->rxbd_ring_vbase = NULL;
837
	card->rxbd_ring_pbase = 0;
838 839 840 841 842 843 844 845 846 847

	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;
848
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
849 850 851 852 853 854 855

	/*
	 * 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;
856
	card->evtbd_rdptr = reg->evt_rollover_ind;
857

858
	card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
A
Avinash Patil 已提交
859 860
				MWIFIEX_MAX_EVT_BD;

861 862
	mwifiex_dbg(adapter, INFO,
		    "info: evtbd_ring: Allocating %d bytes\n",
863
		card->evtbd_ring_size);
864 865 866
	card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
						      card->evtbd_ring_size,
						      &card->evtbd_ring_pbase);
867
	if (!card->evtbd_ring_vbase) {
868 869 870
		mwifiex_dbg(adapter, ERROR,
			    "allocate consistent memory (%d bytes) failed!\n",
			    card->evtbd_ring_size);
871
		return -ENOMEM;
872 873
	}

874 875 876 877 878
	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);
879

880
	return mwifiex_pcie_init_evt_ring(adapter);
881 882 883 884 885 886 887 888
}

/*
 * 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;
889
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
890

891
	mwifiex_cleanup_evt_ring(adapter);
892

893 894 895 896
	if (card->evtbd_ring_vbase)
		pci_free_consistent(card->dev, card->evtbd_ring_size,
				    card->evtbd_ring_vbase,
				    card->evtbd_ring_pbase);
897
	card->evtbd_wrptr = 0;
898
	card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
899 900
	card->evtbd_ring_size = 0;
	card->evtbd_ring_vbase = NULL;
901
	card->evtbd_ring_pbase = 0;
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916

	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) {
917 918
		mwifiex_dbg(adapter, ERROR,
			    "Unable to allocate skb for command response data.\n");
919 920 921
		return -ENOMEM;
	}
	skb_put(skb, MWIFIEX_UPLD_SIZE);
922 923 924
	if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
				   PCI_DMA_FROMDEVICE))
		return -1;
925

926
	card->cmdrsp_buf = skb;
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942

	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;

943
	if (card && card->cmdrsp_buf) {
944 945
		mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
					 PCI_DMA_FROMDEVICE);
946
		dev_kfree_skb_any(card->cmdrsp_buf);
947
	}
948

949
	if (card && card->cmd_buf) {
950 951
		mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
					 PCI_DMA_TODEVICE);
952
	}
953 954 955 956 957 958 959 960 961 962
	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;

963 964 965
	card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
						     &card->sleep_cookie_pbase);
	if (!card->sleep_cookie_vbase) {
966 967
		mwifiex_dbg(adapter, ERROR,
			    "pci_alloc_consistent failed!\n");
968 969 970
		return -ENOMEM;
	}
	/* Init val of Sleep Cookie */
971
	*(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
972

973 974 975
	mwifiex_dbg(adapter, INFO,
		    "alloc_scook: sleep cookie=0x%x\n",
		    *((u32 *)card->sleep_cookie_vbase));
976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991

	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;

992 993 994 995 996
	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;
997 998 999 1000 1001
	}

	return 0;
}

1002 1003 1004 1005 1006 1007 1008 1009
/* 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;

1010
	if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
1011 1012 1013 1014 1015 1016
		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)) {
1017 1018
			mwifiex_dbg(adapter, ERROR,
				    "failed to assert dnld-rdy interrupt.\n");
1019 1020 1021 1022 1023 1024
			return -1;
		}
	}
	return 0;
}

1025
/*
1026
 * This function unmaps and frees downloaded data buffer
1027
 */
1028
static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
1029
{
1030
	struct sk_buff *skb;
A
Avinash Patil 已提交
1031
	u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
1032
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
1033
	struct mwifiex_pfu_buf_desc *desc2;
1034
	struct pcie_service_card *card = adapter->card;
1035
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1036 1037 1038 1039 1040

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

	/* Read the TX ring read pointer set by firmware */
1041
	if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
1042 1043
		mwifiex_dbg(adapter, ERROR,
			    "SEND COMP: failed to read reg->tx_rdptr\n");
1044 1045 1046
		return -1;
	}

1047 1048 1049
	mwifiex_dbg(adapter, DATA,
		    "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
		    card->txbd_rdptr, rdptr);
1050

A
Avinash Patil 已提交
1051
	num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
1052
	/* free from previous txbd_rdptr to current txbd_rdptr */
1053 1054 1055 1056
	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 已提交
1057 1058
		wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
			    reg->tx_start_ptr;
1059 1060

		skb = card->tx_buf_list[wrdoneidx];
1061

1062
		if (skb) {
1063 1064 1065
			mwifiex_dbg(adapter, DATA,
				    "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
				    skb, wrdoneidx);
1066 1067
			mwifiex_unmap_pci_memory(adapter, skb,
						 PCI_DMA_TODEVICE);
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078

			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 已提交
1079 1080

		if (reg->pfu_enabled) {
1081
			desc2 = card->txbd_ring[wrdoneidx];
A
Avinash Patil 已提交
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
			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:
1092
		case PCIE_DEVICE_ID_MARVELL_88W8997:
A
Avinash Patil 已提交
1093 1094 1095 1096
			card->txbd_rdptr += reg->ring_tx_start_ptr;
			break;
		}

1097

1098
		if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
1099
			card->txbd_rdptr = ((card->txbd_rdptr &
1100 1101
					     reg->tx_rollover_ind) ^
					     reg->tx_rollover_ind);
1102 1103 1104 1105 1106 1107
	}

	if (unmap_count)
		adapter->data_sent = false;

	if (card->txbd_flush) {
1108
		if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
			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.
1122
 * Caller must ensure tx_param parameter to this function is not NULL.
1123 1124 1125 1126 1127 1128
 */
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;
1129
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
A
Avinash Patil 已提交
1130
	u32 wrindx, num_tx_buffs, rx_val;
1131 1132
	int ret;
	dma_addr_t buf_pa;
1133 1134
	struct mwifiex_pcie_buf_desc *desc = NULL;
	struct mwifiex_pfu_buf_desc *desc2 = NULL;
1135 1136 1137
	__le16 *tmp;

	if (!(skb->data && skb->len)) {
1138 1139 1140
		mwifiex_dbg(adapter, ERROR,
			    "%s(): invalid parameter <%p, %#x>\n",
			    __func__, skb->data, skb->len);
1141 1142 1143 1144 1145 1146
		return -1;
	}

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

A
Avinash Patil 已提交
1147
	num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
1148 1149
	mwifiex_dbg(adapter, DATA,
		    "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1150 1151
		card->txbd_rdptr, card->txbd_wrptr);
	if (mwifiex_pcie_txbd_not_full(card)) {
1152 1153 1154
		u8 *payload;

		adapter->data_sent = true;
1155
		payload = skb->data;
1156 1157 1158 1159
		tmp = (__le16 *)&payload[0];
		*tmp = cpu_to_le16((u16)skb->len);
		tmp = (__le16 *)&payload[2];
		*tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
1160

1161
		if (mwifiex_map_pci_memory(adapter, skb, skb->len,
1162 1163 1164
					   PCI_DMA_TODEVICE))
			return -1;

A
Avinash Patil 已提交
1165
		wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
1166
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1167
		card->tx_buf_list[wrindx] = skb;
1168

A
Avinash Patil 已提交
1169
		if (reg->pfu_enabled) {
1170
			desc2 = card->txbd_ring[wrindx];
A
Avinash Patil 已提交
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
			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:
1190
		case PCIE_DEVICE_ID_MARVELL_88W8997:
A
Avinash Patil 已提交
1191 1192 1193 1194 1195
			card->txbd_wrptr += reg->ring_tx_start_ptr;
			break;
		}

		if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
1196
			card->txbd_wrptr = ((card->txbd_wrptr &
1197 1198
						reg->tx_rollover_ind) ^
						reg->tx_rollover_ind);
1199

A
Avinash Patil 已提交
1200
		rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
1201 1202
		/* Write the TX ring write pointer in to reg->tx_wrptr */
		if (mwifiex_write_reg(adapter, reg->tx_wrptr,
A
Avinash Patil 已提交
1203
				      card->txbd_wrptr | rx_val)) {
1204 1205
			mwifiex_dbg(adapter, ERROR,
				    "SEND DATA: failed to write reg->tx_wrptr\n");
1206 1207
			ret = -1;
			goto done_unmap;
1208
		}
1209 1210 1211
		if ((mwifiex_pcie_txbd_not_full(card)) &&
		    tx_param->next_pkt_len) {
			/* have more packets and TxBD still can hold more */
1212 1213
			mwifiex_dbg(adapter, DATA,
				    "SEND DATA: delay dnld-rdy interrupt.\n");
1214 1215 1216 1217 1218
			adapter->data_sent = false;
		} else {
			/* Send the TX ready interrupt */
			if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
					      CPU_INTR_DNLD_RDY)) {
1219 1220
				mwifiex_dbg(adapter, ERROR,
					    "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1221 1222 1223
				ret = -1;
				goto done_unmap;
			}
1224
		}
1225 1226 1227 1228
		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);
1229
	} else {
1230 1231
		mwifiex_dbg(adapter, DATA,
			    "info: TX Ring full, can't send packets to fw\n");
1232 1233 1234 1235
		adapter->data_sent = true;
		/* Send the TX ready interrupt */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY))
1236 1237
			mwifiex_dbg(adapter, ERROR,
				    "SEND DATA: failed to assert door-bell intr\n");
1238 1239 1240
		return -EBUSY;
	}

1241 1242
	return -EINPROGRESS;
done_unmap:
1243
	mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1244
	card->tx_buf_list[wrindx] = NULL;
A
Avinash Patil 已提交
1245 1246 1247 1248 1249
	if (reg->pfu_enabled)
		memset(desc2, 0, sizeof(*desc2));
	else
		memset(desc, 0, sizeof(*desc));

1250
	return ret;
1251 1252 1253 1254 1255 1256 1257 1258 1259
}

/*
 * 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;
1260
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
A
Avinash Patil 已提交
1261
	u32 wrptr, rd_index, tx_val;
1262
	dma_addr_t buf_pa;
1263 1264
	int ret = 0;
	struct sk_buff *skb_tmp = NULL;
1265
	struct mwifiex_pcie_buf_desc *desc;
A
Avinash Patil 已提交
1266
	struct mwifiex_pfu_buf_desc *desc2;
1267

1268 1269 1270
	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);

1271
	/* Read the RX ring Write pointer set by firmware */
1272
	if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
1273 1274
		mwifiex_dbg(adapter, ERROR,
			    "RECV DATA: failed to read reg->rx_wrptr\n");
1275 1276 1277
		ret = -1;
		goto done;
	}
1278
	card->rxbd_wrptr = wrptr;
1279

1280 1281 1282 1283
	while (((wrptr & reg->rx_mask) !=
		(card->rxbd_rdptr & reg->rx_mask)) ||
	       ((wrptr & reg->rx_rollover_ind) ==
		(card->rxbd_rdptr & reg->rx_rollover_ind))) {
1284 1285
		struct sk_buff *skb_data;
		u16 rx_len;
1286
		__le16 pkt_len;
1287

1288
		rd_index = card->rxbd_rdptr & reg->rx_mask;
1289 1290
		skb_data = card->rx_buf_list[rd_index];

1291 1292 1293 1294 1295 1296
		/* 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;

1297
		mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
1298 1299
		card->rx_buf_list[rd_index] = NULL;

1300
		/* Get data length from interface header -
1301 1302 1303 1304
		 * first 2 bytes for len, next 2 bytes is for type
		 */
		pkt_len = *((__le16 *)skb_data->data);
		rx_len = le16_to_cpu(pkt_len);
1305 1306
		if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
			    rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
1307 1308 1309
			mwifiex_dbg(adapter, ERROR,
				    "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
				    rx_len, card->rxbd_rdptr, wrptr);
1310 1311 1312
			dev_kfree_skb_any(skb_data);
		} else {
			skb_put(skb_data, rx_len);
1313 1314 1315
			mwifiex_dbg(adapter, DATA,
				    "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
				    card->rxbd_rdptr, wrptr, rx_len);
1316
			skb_pull(skb_data, INTF_HEADER_LEN);
1317 1318 1319 1320 1321 1322 1323
			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);
			}
1324
		}
1325

1326 1327
		skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
						      GFP_KERNEL | GFP_DMA);
1328
		if (!skb_tmp) {
1329 1330
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb.\n");
1331
			return -ENOMEM;
1332 1333
		}

1334 1335 1336 1337 1338
		if (mwifiex_map_pci_memory(adapter, skb_tmp,
					   MWIFIEX_RX_DATA_BUF_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;

1339
		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
1340

1341 1342 1343
		mwifiex_dbg(adapter, INFO,
			    "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
			    skb_tmp, rd_index);
1344
		card->rx_buf_list[rd_index] = skb_tmp;
A
Avinash Patil 已提交
1345 1346

		if (reg->pfu_enabled) {
1347
			desc2 = card->rxbd_ring[rd_index];
A
Avinash Patil 已提交
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
			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;
		}
1359

1360
		if ((++card->rxbd_rdptr & reg->rx_mask) ==
1361 1362
							MWIFIEX_MAX_TXRX_BD) {
			card->rxbd_rdptr = ((card->rxbd_rdptr &
1363 1364
					     reg->rx_rollover_ind) ^
					     reg->rx_rollover_ind);
1365
		}
1366 1367 1368
		mwifiex_dbg(adapter, DATA,
			    "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
			    card->rxbd_rdptr, wrptr);
1369

A
Avinash Patil 已提交
1370
		tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
1371 1372
		/* Write the RX ring read pointer in to reg->rx_rdptr */
		if (mwifiex_write_reg(adapter, reg->rx_rdptr,
A
Avinash Patil 已提交
1373
				      card->rxbd_rdptr | tx_val)) {
1374 1375
			mwifiex_dbg(adapter, DATA,
				    "RECV DATA: failed to write reg->rx_rdptr\n");
1376 1377 1378 1379 1380
			ret = -1;
			goto done;
		}

		/* Read the RX ring Write pointer set by firmware */
1381
		if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
1382 1383
			mwifiex_dbg(adapter, ERROR,
				    "RECV DATA: failed to read reg->rx_wrptr\n");
1384 1385 1386
			ret = -1;
			goto done;
		}
1387 1388
		mwifiex_dbg(adapter, DATA,
			    "info: RECV DATA: Rcvd packet from fw successfully\n");
1389
		card->rxbd_wrptr = wrptr;
1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
	}

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)
{
1402 1403
	dma_addr_t buf_pa;
	struct pcie_service_card *card = adapter->card;
1404
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1405

1406
	if (!(skb->data && skb->len)) {
1407 1408 1409
		mwifiex_dbg(adapter, ERROR,
			    "Invalid parameter in %s <%p. len %d>\n",
			    __func__, skb->data, skb->len);
1410 1411 1412
		return -1;
	}

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

1416
	buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
1417

1418 1419 1420 1421
	/* 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)) {
1422 1423 1424
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to write download command to boot code.\n",
			    __func__);
1425
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1426 1427 1428
		return -1;
	}

1429 1430 1431 1432
	/* Write the upper 32bits of the physical address to high command
	 * address scratch register
	 */
	if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
1433
			      (u32)((u64)buf_pa >> 32))) {
1434 1435 1436
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to write download command to boot code.\n",
			    __func__);
1437
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1438 1439 1440
		return -1;
	}

1441 1442
	/* Write the command length to cmd_size scratch register */
	if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
1443 1444 1445
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to write command len to cmd_size scratch reg\n",
			    __func__);
1446
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1447 1448 1449 1450 1451 1452
		return -1;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
1453 1454
		mwifiex_dbg(adapter, ERROR,
			    "%s: failed to assert door-bell intr\n", __func__);
1455
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1456 1457 1458 1459 1460 1461
		return -1;
	}

	return 0;
}

1462 1463 1464 1465 1466 1467
/* 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;
1468
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
A
Avinash Patil 已提交
1469
	int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
1470

1471
	/* Write the RX ring read pointer in to reg->rx_rdptr */
A
Avinash Patil 已提交
1472 1473
	if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
			      tx_wrap)) {
1474 1475
		mwifiex_dbg(adapter, ERROR,
			    "RECV DATA: failed to write reg->rx_rdptr\n");
1476 1477 1478 1479 1480 1481
		return -1;
	}
	return 0;
}

/* This function downloads commands to the device
1482 1483 1484 1485 1486
 */
static int
mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
1487
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1488
	int ret = 0;
1489 1490
	dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
	u8 *payload = (u8 *)skb->data;
1491 1492

	if (!(skb->data && skb->len)) {
1493 1494 1495
		mwifiex_dbg(adapter, ERROR,
			    "Invalid parameter in %s <%p, %#x>\n",
			    __func__, skb->data, skb->len);
1496 1497 1498 1499 1500
		return -1;
	}

	/* Make sure a command response buffer is available */
	if (!card->cmdrsp_buf) {
1501 1502
		mwifiex_dbg(adapter, ERROR,
			    "No response buffer available, send command failed\n");
1503 1504 1505
		return -EBUSY;
	}

1506 1507
	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);
1508 1509

	adapter->cmd_sent = true;
1510 1511 1512 1513 1514 1515 1516 1517

	*(__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;
1518 1519 1520

	/* To send a command, the driver will:
		1. Write the 64bit physical address of the data buffer to
1521
		   cmd response address low  + cmd response address high
1522 1523 1524 1525 1526 1527 1528 1529
		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) {
1530
		cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
1531 1532
		/* Write the lower 32bits of the cmdrsp buffer physical
		   address */
1533
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
1534
				      (u32)cmdrsp_buf_pa)) {
1535 1536
			mwifiex_dbg(adapter, ERROR,
				    "Failed to write download cmd to boot code.\n");
1537 1538 1539 1540 1541
			ret = -1;
			goto done;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
1542
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
1543
				      (u32)((u64)cmdrsp_buf_pa >> 32))) {
1544 1545
			mwifiex_dbg(adapter, ERROR,
				    "Failed to write download cmd to boot code.\n");
1546 1547 1548 1549 1550
			ret = -1;
			goto done;
		}
	}

1551
	cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
1552 1553 1554
	/* 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)) {
1555 1556
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write download cmd to boot code.\n");
1557 1558 1559
		ret = -1;
		goto done;
	}
1560 1561
	/* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
	if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
1562
			      (u32)((u64)cmd_buf_pa >> 32))) {
1563 1564
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write download cmd to boot code.\n");
1565 1566 1567 1568
		ret = -1;
		goto done;
	}

1569 1570 1571
	/* Write the command length to reg->cmd_size */
	if (mwifiex_write_reg(adapter, reg->cmd_size,
			      card->cmd_buf->len)) {
1572 1573
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write cmd len to reg->cmd_size\n");
1574 1575 1576 1577 1578 1579 1580
		ret = -1;
		goto done;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
1581 1582
		mwifiex_dbg(adapter, ERROR,
			    "Failed to assert door-bell intr\n");
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
		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;
1600
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1601
	struct sk_buff *skb = card->cmdrsp_buf;
1602
	int count = 0;
1603 1604
	u16 rx_len;
	__le16 pkt_len;
1605

1606 1607
	mwifiex_dbg(adapter, CMD,
		    "info: Rx CMD Response\n");
1608

1609
	mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
1610

1611 1612 1613 1614 1615 1616 1617
	/* 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;
	}

1618 1619 1620 1621 1622
	pkt_len = *((__le16 *)skb->data);
	rx_len = le16_to_cpu(pkt_len);
	skb_trim(skb, rx_len);
	skb_pull(skb, INTF_HEADER_LEN);

1623 1624
	if (!adapter->curr_cmd) {
		if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
1625 1626
			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
							   skb->len);
1627 1628 1629 1630
			mwifiex_pcie_enable_host_int(adapter);
			if (mwifiex_write_reg(adapter,
					      PCIE_CPU_INT_EVENT,
					      CPU_INTR_SLEEP_CFM_DONE)) {
1631 1632
				mwifiex_dbg(adapter, ERROR,
					    "Write register failed\n");
1633 1634
				return -1;
			}
1635 1636
			mwifiex_delay_for_sleep_cookie(adapter,
						       MWIFIEX_MAX_DELAY_COUNT);
1637 1638
			while (reg->sleep_cookie && (count++ < 10) &&
			       mwifiex_pcie_ok_to_access_hw(adapter))
1639
				usleep_range(50, 60);
1640
		} else {
1641 1642
			mwifiex_dbg(adapter, ERROR,
				    "There is no command but got cmdrsp\n");
1643
		}
1644 1645
		memcpy(adapter->upld_buf, skb->data,
		       min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
1646
		skb_push(skb, INTF_HEADER_LEN);
1647 1648 1649
		if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;
1650
	} else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1651
		adapter->curr_cmd->resp_skb = skb;
1652 1653 1654 1655 1656 1657 1658 1659
		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. */
1660
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
1661 1662
			mwifiex_dbg(adapter, ERROR,
				    "cmd_done: failed to clear cmd_rsp_addr_lo\n");
1663 1664 1665 1666
			return -1;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
1667
		if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
1668 1669
			mwifiex_dbg(adapter, ERROR,
				    "cmd_done: failed to clear cmd_rsp_addr_hi\n");
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
			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);
1688 1689 1690 1691 1692
		if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;
	}

1693 1694 1695 1696 1697 1698 1699 1700 1701
	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;
1702
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1703 1704
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr, event;
1705
	struct mwifiex_evt_buf_desc *desc;
1706 1707 1708

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

	if (adapter->event_received) {
1711 1712 1713
		mwifiex_dbg(adapter, EVENT,
			    "info: Event being processed,\t"
			    "do not process this interrupt just yet\n");
1714 1715 1716 1717
		return 0;
	}

	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1718 1719
		mwifiex_dbg(adapter, ERROR,
			    "info: Invalid read pointer...\n");
1720 1721 1722 1723
		return -1;
	}

	/* Read the event ring write pointer set by firmware */
1724
	if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
1725 1726
		mwifiex_dbg(adapter, ERROR,
			    "EventReady: failed to read reg->evt_wrptr\n");
1727 1728 1729
		return -1;
	}

1730 1731 1732
	mwifiex_dbg(adapter, EVENT,
		    "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
		    card->evtbd_rdptr, wrptr);
1733 1734
	if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
					      & MWIFIEX_EVTBD_MASK)) ||
1735 1736
	    ((wrptr & reg->evt_rollover_ind) ==
	     (card->evtbd_rdptr & reg->evt_rollover_ind))) {
1737 1738 1739 1740
		struct sk_buff *skb_cmd;
		__le16 data_len = 0;
		u16 evt_len;

1741 1742
		mwifiex_dbg(adapter, INFO,
			    "info: Read Index: %d\n", rdptr);
1743
		skb_cmd = card->evt_buf_list[rdptr];
1744
		mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
1745

1746 1747 1748
		/* 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;
1749 1750
		desc = card->evtbd_ring[rdptr];
		memset(desc, 0, sizeof(*desc));
1751 1752 1753 1754 1755 1756 1757

		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);
1758
		skb_trim(skb_cmd, evt_len);
1759
		skb_pull(skb_cmd, INTF_HEADER_LEN);
1760 1761
		mwifiex_dbg(adapter, EVENT,
			    "info: Event length: %d\n", evt_len);
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774

		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.
		*/
1775 1776 1777
	} else {
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_EVENT_DONE)) {
1778 1779
			mwifiex_dbg(adapter, ERROR,
				    "Write register failed\n");
1780 1781
			return -1;
		}
1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793
	}

	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;
1794
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1795 1796 1797
	int ret = 0;
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr;
1798
	struct mwifiex_evt_buf_desc *desc;
1799 1800 1801 1802

	if (!skb)
		return 0;

1803
	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1804 1805 1806
		mwifiex_dbg(adapter, ERROR,
			    "event_complete: Invalid rdptr 0x%x\n",
			    rdptr);
1807
		return -EINVAL;
1808
	}
1809 1810

	/* Read the event ring write pointer set by firmware */
1811
	if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
1812 1813
		mwifiex_dbg(adapter, ERROR,
			    "event_complete: failed to read reg->evt_wrptr\n");
1814
		return -1;
1815 1816 1817 1818
	}

	if (!card->evt_buf_list[rdptr]) {
		skb_push(skb, INTF_HEADER_LEN);
1819
		skb_put(skb, MAX_EVENT_SIZE - skb->len);
1820 1821 1822 1823
		if (mwifiex_map_pci_memory(adapter, skb,
					   MAX_EVENT_SIZE,
					   PCI_DMA_FROMDEVICE))
			return -1;
1824
		card->evt_buf_list[rdptr] = skb;
1825
		desc = card->evtbd_ring[rdptr];
1826
		desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
1827 1828
		desc->len = (u16)skb->len;
		desc->flags = 0;
1829 1830
		skb = NULL;
	} else {
1831 1832 1833
		mwifiex_dbg(adapter, ERROR,
			    "info: ERROR: buf still valid at index %d, <%p, %p>\n",
			    rdptr, card->evt_buf_list[rdptr], skb);
1834 1835 1836 1837
	}

	if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
		card->evtbd_rdptr = ((card->evtbd_rdptr &
1838 1839
					reg->evt_rollover_ind) ^
					reg->evt_rollover_ind);
1840 1841
	}

1842 1843 1844
	mwifiex_dbg(adapter, EVENT,
		    "info: Updated <Rd: 0x%x, Wr: 0x%x>",
		    card->evtbd_rdptr, wrptr);
1845

1846 1847 1848
	/* Write the event ring read pointer in to reg->evt_rdptr */
	if (mwifiex_write_reg(adapter, reg->evt_rdptr,
			      card->evtbd_rdptr)) {
1849 1850
		mwifiex_dbg(adapter, ERROR,
			    "event_complete: failed to read reg->evt_rdptr\n");
1851
		return -1;
1852 1853
	}

1854 1855
	mwifiex_dbg(adapter, EVENT,
		    "info: Check Events Again\n");
1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877
	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;
1878
	struct pcie_service_card *card = adapter->card;
1879
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
1880 1881

	if (!firmware || !firmware_len) {
1882 1883
		mwifiex_dbg(adapter, ERROR,
			    "No firmware image found! Terminating download\n");
1884 1885 1886
		return -1;
	}

1887 1888 1889
	mwifiex_dbg(adapter, INFO,
		    "info: Downloading FW image (%d bytes)\n",
		    firmware_len);
1890 1891

	if (mwifiex_pcie_disable_host_int(adapter)) {
1892 1893
		mwifiex_dbg(adapter, ERROR,
			    "%s: Disabling interrupts failed.\n", __func__);
1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911
		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++) {
1912
			ret = mwifiex_read_reg(adapter, reg->cmd_size,
1913 1914
					       &len);
			if (ret) {
1915 1916
				mwifiex_dbg(adapter, FATAL,
					    "Failed reading len from boot code\n");
1917 1918 1919 1920
				goto done;
			}
			if (len)
				break;
1921
			usleep_range(10, 20);
1922 1923 1924 1925 1926
		}

		if (!len) {
			break;
		} else if (len > MWIFIEX_UPLD_SIZE) {
1927 1928 1929
			mwifiex_dbg(adapter, ERROR,
				    "FW download failure @ %d, invalid length %d\n",
				    offset, len);
1930 1931 1932 1933 1934 1935 1936 1937 1938
			ret = -1;
			goto done;
		}

		txlen = len;

		if (len & BIT(0)) {
			block_retry_cnt++;
			if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1939 1940 1941
				mwifiex_dbg(adapter, ERROR,
					    "FW download failure @ %d, over max\t"
					    "retry count\n", offset);
1942 1943 1944
				ret = -1;
				goto done;
			}
1945 1946 1947 1948
			mwifiex_dbg(adapter, ERROR,
				    "FW CRC error indicated by the\t"
				    "helper: len = 0x%04X, txlen = %d\n",
				    len, txlen);
1949 1950 1951 1952 1953 1954 1955 1956 1957 1958
			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;

1959
			mwifiex_dbg(adapter, INFO, ".");
1960

1961 1962
			tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
				    card->pcie.blksz_fw_dl;
1963 1964 1965 1966 1967 1968

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

		skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
1969
		skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
1970 1971 1972

		/* Send the boot command to device */
		if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
1973 1974
			mwifiex_dbg(adapter, ERROR,
				    "Failed to send firmware download command\n");
1975 1976 1977
			ret = -1;
			goto done;
		}
1978

1979 1980 1981 1982
		/* Wait for the command done interrupt */
		do {
			if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
					     &ireg_intr)) {
1983 1984 1985 1986
				mwifiex_dbg(adapter, ERROR,
					    "%s: Failed to read\t"
					    "interrupt status during fw dnld.\n",
					    __func__);
1987 1988
				mwifiex_unmap_pci_memory(adapter, skb,
							 PCI_DMA_TODEVICE);
1989 1990 1991 1992 1993
				ret = -1;
				goto done;
			}
		} while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
			 CPU_INTR_DOOR_BELL);
1994

1995
		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
1996

1997 1998 1999
		offset += txlen;
	} while (true);

2000 2001
	mwifiex_dbg(adapter, MSG,
		    "info: FW download over, size %d bytes\n", offset);
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016

	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;
2017
	u32 firmware_stat;
2018 2019
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2020 2021 2022 2023
	u32 tries;

	/* Mask spurios interrupts */
	if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
2024
			      HOST_INTR_MASK)) {
2025 2026
		mwifiex_dbg(adapter, ERROR,
			    "Write register failed\n");
2027 2028 2029
		return -1;
	}

2030 2031
	mwifiex_dbg(adapter, INFO,
		    "Setting driver ready signature\n");
2032 2033
	if (mwifiex_write_reg(adapter, reg->drv_rdy,
			      FIRMWARE_READY_PCIE)) {
2034 2035
		mwifiex_dbg(adapter, ERROR,
			    "Failed to write driver ready signature\n");
2036 2037 2038 2039 2040
		return -1;
	}

	/* Wait for firmware initialization event */
	for (tries = 0; tries < poll_num; tries++) {
2041
		if (mwifiex_read_reg(adapter, reg->fw_status,
2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
				     &firmware_stat))
			ret = -1;
		else
			ret = 0;
		if (ret)
			continue;
		if (firmware_stat == FIRMWARE_READY_PCIE) {
			ret = 0;
			break;
		} else {
2052
			msleep(100);
2053 2054 2055 2056
			ret = -1;
		}
	}

2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078
	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,
			    "PCI-E is not the winner <%#x,%d>, exit dnld\n",
			    ret, adapter->winner);
2079 2080 2081 2082 2083 2084 2085 2086
	}

	return ret;
}

/*
 * This function reads the interrupt status from card.
 */
2087 2088
static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter,
				     int msg_id)
2089 2090 2091
{
	u32 pcie_ireg;
	unsigned long flags;
2092
	struct pcie_service_card *card = adapter->card;
2093 2094 2095 2096

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		return;

2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
	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;
2108 2109 2110 2111 2112 2113 2114


		mwifiex_pcie_disable_host_int(adapter);

		/* Clear the pending interrupts */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
				      ~pcie_ireg)) {
2115 2116
			mwifiex_dbg(adapter, ERROR,
				    "Write register failed\n");
2117 2118
			return;
		}
2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130
	}

	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);
2131
	}
2132 2133 2134 2135 2136

	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);
2137 2138 2139 2140 2141 2142 2143 2144 2145 2146
}

/*
 * 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)
{
2147 2148
	struct mwifiex_msix_context *ctx = context;
	struct pci_dev *pdev = ctx->dev;
2149 2150 2151 2152
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;

	if (!pdev) {
2153
		pr_err("info: %s: pdev is NULL\n", __func__);
2154 2155 2156
		goto exit;
	}

2157
	card = pci_get_drvdata(pdev);
2158
	if (!card || !card->adapter) {
2159 2160
		pr_err("info: %s: card=%p adapter=%p\n", __func__, card,
		       card ? card->adapter : NULL);
2161 2162 2163 2164 2165 2166 2167
		goto exit;
	}
	adapter = card->adapter;

	if (adapter->surprise_removed)
		goto exit;

2168 2169 2170 2171 2172
	if (card->msix_enable)
		mwifiex_interrupt_status(adapter, ctx->msg_id);
	else
		mwifiex_interrupt_status(adapter, -1);

2173
	mwifiex_queue_main_work(adapter);
2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191

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.
 */
2192
static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
2193 2194
{
	int ret;
2195
	u32 pcie_ireg;
2196 2197 2198 2199
	unsigned long flags;

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

2204 2205 2206
	while (pcie_ireg & HOST_INTR_MASK) {
		if (pcie_ireg & HOST_INTR_DNLD_DONE) {
			pcie_ireg &= ~HOST_INTR_DNLD_DONE;
2207 2208
			mwifiex_dbg(adapter, INTR,
				    "info: TX DNLD Done\n");
2209 2210 2211
			ret = mwifiex_pcie_send_data_complete(adapter);
			if (ret)
				return ret;
2212
		}
2213 2214
		if (pcie_ireg & HOST_INTR_UPLD_RDY) {
			pcie_ireg &= ~HOST_INTR_UPLD_RDY;
2215 2216
			mwifiex_dbg(adapter, INTR,
				    "info: Rx DATA\n");
2217 2218 2219 2220
			ret = mwifiex_pcie_process_recv_data(adapter);
			if (ret)
				return ret;
		}
2221 2222
		if (pcie_ireg & HOST_INTR_EVENT_RDY) {
			pcie_ireg &= ~HOST_INTR_EVENT_RDY;
2223 2224
			mwifiex_dbg(adapter, INTR,
				    "info: Rx EVENT\n");
2225 2226 2227 2228 2229
			ret = mwifiex_pcie_process_event_ready(adapter);
			if (ret)
				return ret;
		}

2230 2231
		if (pcie_ireg & HOST_INTR_CMD_DONE) {
			pcie_ireg &= ~HOST_INTR_CMD_DONE;
2232
			if (adapter->cmd_sent) {
2233 2234
				mwifiex_dbg(adapter, INTR,
					    "info: CMD sent Interrupt\n");
2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245
				adapter->cmd_sent = false;
			}
			/* Handle command response */
			ret = mwifiex_pcie_process_cmd_complete(adapter);
			if (ret)
				return ret;
		}

		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
					     &pcie_ireg)) {
2246 2247
				mwifiex_dbg(adapter, ERROR,
					    "Read register failed\n");
2248 2249 2250 2251 2252
				return -1;
			}

			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
				if (mwifiex_write_reg(adapter,
2253 2254
						      PCIE_HOST_INT_STATUS,
						      ~pcie_ireg)) {
2255 2256
					mwifiex_dbg(adapter, ERROR,
						    "Write register failed\n");
2257 2258 2259 2260 2261 2262
					return -1;
				}
			}

		}
	}
2263 2264 2265
	mwifiex_dbg(adapter, INTR,
		    "info: cmd_sent=%d data_sent=%d\n",
		    adapter->cmd_sent, adapter->data_sent);
2266 2267
	if (adapter->ps_state != PS_STATE_SLEEP)
		mwifiex_pcie_enable_host_int(adapter);
2268 2269 2270 2271

	return 0;
}

2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 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 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334
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);
}

2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348
/*
 * 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)
{
2349
	if (!skb) {
2350 2351
		mwifiex_dbg(adapter, ERROR,
			    "Passed NULL skb to %s\n", __func__);
2352 2353 2354 2355
		return -1;
	}

	if (type == MWIFIEX_TYPE_DATA)
2356
		return mwifiex_pcie_send_data(adapter, skb, tx_param);
2357 2358 2359 2360 2361 2362
	else if (type == MWIFIEX_TYPE_CMD)
		return mwifiex_pcie_send_cmd(adapter, skb);

	return 0;
}

2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373
/* 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;
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

	ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
	if (ret) {
2374 2375
		mwifiex_dbg(adapter, ERROR,
			    "PCIE write err\n");
2376 2377 2378 2379 2380 2381 2382 2383 2384 2385
		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;
		if (ctrl_data != FW_DUMP_HOST_READY) {
2386 2387
			mwifiex_dbg(adapter, WARN,
				    "The ctrl reg was changed, re-try again!\n");
2388 2389
			ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
						FW_DUMP_HOST_READY);
2390
			if (ret) {
2391 2392
				mwifiex_dbg(adapter, ERROR,
					    "PCIE write err\n");
2393 2394 2395 2396 2397 2398
				return RDWR_STATUS_FAILURE;
			}
		}
		usleep_range(100, 200);
	}

2399
	mwifiex_dbg(adapter, ERROR, "Fail to pull ctrl_data\n");
2400 2401 2402 2403
	return RDWR_STATUS_FAILURE;
}

/* This function dump firmware memory to file */
2404
static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2405 2406 2407 2408 2409 2410 2411
{
	struct pcie_service_card *card = adapter->card;
	const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
	unsigned int reg, reg_start, reg_end;
	u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
	enum rdwr_status stat;
	u32 memory_size;
2412
	int ret;
2413

2414
	if (!card->pcie.can_dump_fw)
2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426
		return;

	for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
		struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];

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

2427
	mwifiex_dbg(adapter, DUMP, "== mwifiex firmware dump start ==\n");
2428 2429 2430 2431

	/* Read the number of the memories which will dump */
	stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
	if (stat == RDWR_STATUS_FAILURE)
2432
		return;
2433 2434 2435 2436 2437 2438 2439 2440 2441 2442

	reg = creg->fw_dump_start;
	mwifiex_read_reg_byte(adapter, reg, &dump_num);

	/* Read the length of every memory which will dump */
	for (idx = 0; idx < dump_num; idx++) {
		struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];

		stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
		if (stat == RDWR_STATUS_FAILURE)
2443
			return;
2444 2445 2446 2447 2448 2449 2450 2451 2452 2453

		memory_size = 0;
		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));
			reg++;
		}

		if (memory_size == 0) {
2454
			mwifiex_dbg(adapter, MSG, "Firmware dump Finished!\n");
2455 2456 2457
			ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
						FW_DUMP_READ_DONE);
			if (ret) {
2458
				mwifiex_dbg(adapter, ERROR, "PCIE write err\n");
2459
				return;
2460
			}
2461 2462 2463
			break;
		}

2464 2465
		mwifiex_dbg(adapter, DUMP,
			    "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2466 2467 2468
		entry->mem_ptr = vmalloc(memory_size + 1);
		entry->mem_size = memory_size;
		if (!entry->mem_ptr) {
2469 2470
			mwifiex_dbg(adapter, ERROR,
				    "Vmalloc %s failed\n", entry->mem_name);
2471
			return;
2472 2473 2474 2475 2476
		}
		dbg_ptr = entry->mem_ptr;
		end_ptr = dbg_ptr + memory_size;

		doneflag = entry->done_flag;
2477 2478
		mwifiex_dbg(adapter, DUMP, "Start %s output, please wait...\n",
			    entry->mem_name);
2479 2480 2481 2482

		do {
			stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
			if (RDWR_STATUS_FAILURE == stat)
2483
				return;
2484 2485 2486 2487 2488

			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);
2489
				if (dbg_ptr < end_ptr) {
2490
					dbg_ptr++;
2491
				} else {
2492 2493
					mwifiex_dbg(adapter, ERROR,
						    "Allocated buf not enough\n");
2494
					return;
2495
				}
2496 2497 2498 2499 2500
			}

			if (stat != RDWR_STATUS_DONE)
				continue;

2501 2502 2503
			mwifiex_dbg(adapter, DUMP,
				    "%s done: size=0x%tx\n",
				    entry->mem_name, dbg_ptr - entry->mem_ptr);
2504 2505 2506
			break;
		} while (true);
	}
2507
	mwifiex_dbg(adapter, DUMP, "== mwifiex firmware dump end ==\n");
2508 2509
}

2510 2511 2512 2513
static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
{
	mwifiex_drv_info_dump(adapter);
	mwifiex_pcie_fw_dump(adapter);
2514
	mwifiex_upload_device_dump(adapter);
2515 2516
}

2517 2518
static unsigned long iface_work_flags;
static struct mwifiex_adapter *save_adapter;
2519 2520
static void mwifiex_pcie_work(struct work_struct *work)
{
2521
	if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
2522
			       &iface_work_flags))
2523
		mwifiex_pcie_device_dump_work(save_adapter);
2524 2525
}

2526
static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
2527
/* This function dumps FW information */
2528
static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
2529
{
2530
	save_adapter = adapter;
2531
	if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
2532 2533
		return;

2534
	set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
2535

2536
	schedule_work(&pcie_work);
2537 2538
}

2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553
/*
 * 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;
2554
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2555 2556 2557 2558 2559 2560 2561 2562 2563

	pci_set_drvdata(pdev, card);

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

	pci_set_master(pdev);

X
Xinming Hu 已提交
2564
	pr_notice("try set_consistent_dma_mask(32)\n");
2565 2566
	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
X
Xinming Hu 已提交
2567
		pr_err("set_dma_mask(32) failed\n");
2568 2569 2570 2571 2572
		goto err_set_dma_mask;
	}

	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
X
Xinming Hu 已提交
2573
		pr_err("set_consistent_dma_mask(64) failed\n");
2574 2575 2576 2577 2578
		goto err_set_dma_mask;
	}

	ret = pci_request_region(pdev, 0, DRV_NAME);
	if (ret) {
X
Xinming Hu 已提交
2579
		pr_err("req_reg(0) error\n");
2580 2581 2582 2583
		goto err_req_region0;
	}
	card->pci_mmap = pci_iomap(pdev, 0, 0);
	if (!card->pci_mmap) {
X
Xinming Hu 已提交
2584
		pr_err("iomap(0) error\n");
2585
		ret = -EIO;
2586 2587 2588 2589
		goto err_iomap0;
	}
	ret = pci_request_region(pdev, 2, DRV_NAME);
	if (ret) {
X
Xinming Hu 已提交
2590
		pr_err("req_reg(2) error\n");
2591 2592 2593 2594
		goto err_req_region2;
	}
	card->pci_mmap1 = pci_iomap(pdev, 2, 0);
	if (!card->pci_mmap1) {
X
Xinming Hu 已提交
2595
		pr_err("iomap(2) error\n");
2596
		ret = -EIO;
2597 2598 2599
		goto err_iomap2;
	}

X
Xinming Hu 已提交
2600 2601
	pr_notice("PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
		  card->pci_mmap, card->pci_mmap1);
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615

	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;
2616 2617 2618 2619 2620 2621 2622
	if (reg->sleep_cookie) {
		ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
		if (ret)
			goto err_alloc_cookie;
	} else {
		card->sleep_cookie_vbase = NULL;
	}
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662
	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:
	pci_set_drvdata(pdev, NULL);
	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;
2663
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2664 2665

	if (user_rmmod) {
2666 2667
		mwifiex_dbg(adapter, INFO,
			    "Clearing driver ready signature\n");
2668
		if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
2669 2670
			mwifiex_dbg(adapter, ERROR,
				    "Failed to write driver not-ready signature\n");
2671 2672 2673 2674 2675
	}

	if (pdev) {
		pci_iounmap(pdev, card->pci_mmap);
		pci_iounmap(pdev, card->pci_mmap1);
2676
		pci_disable_device(pdev);
2677 2678
		pci_release_region(pdev, 2);
		pci_release_region(pdev, 0);
2679 2680
		pci_set_drvdata(pdev, NULL);
	}
2681
	kfree(card);
2682 2683
}

2684 2685
static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
{
2686
	int ret, i, j;
2687 2688 2689
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;

2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722
	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;
			}
		}
	}

2723 2724 2725 2726 2727 2728 2729
	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);

2730 2731
	card->share_irq_ctx.dev = pdev;
	card->share_irq_ctx.msg_id = -1;
2732
	ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2733
			  "MRVL_PCIE", &card->share_irq_ctx);
2734 2735 2736 2737 2738 2739 2740 2741 2742
	if (ret) {
		pr_err("request_irq failed: ret=%d\n", ret);
		adapter->card = NULL;
		return -1;
	}

	return 0;
}

2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754
/*
 * 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;
	struct pci_dev *pdev = card->dev;

	/* save adapter pointer in card */
	card->adapter = adapter;
X
Xinming Hu 已提交
2755
	adapter->dev = &pdev->dev;
2756

2757
	if (mwifiex_pcie_request_irq(adapter))
2758 2759
		return -1;

2760
	adapter->tx_buf_size = card->pcie.tx_buf_size;
2761 2762
	adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
	adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
2763
	strcpy(adapter->fw_name, card->pcie.firmware);
2764
	adapter->ext_scan = card->pcie.can_ext_scan;
2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777

	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;
2778
	const struct mwifiex_pcie_card_reg *reg;
2779 2780
	struct pci_dev *pdev = card->dev;
	int i;
2781 2782

	if (card) {
2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800
		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);
	       }
2801

2802 2803 2804 2805
		reg = card->pcie.reg;
		if (reg->sleep_cookie)
			mwifiex_pcie_delete_sleep_cookie_buf(adapter);

2806 2807 2808 2809 2810
		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;
2811 2812 2813 2814 2815 2816 2817
	}
}

static struct mwifiex_if_ops pcie_ops = {
	.init_if =			mwifiex_pcie_init,
	.cleanup_if =			mwifiex_pcie_cleanup,
	.check_fw_status =		mwifiex_check_fw_status,
2818
	.check_winner_status =          mwifiex_check_winner_status,
2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832
	.prog_fw =			mwifiex_prog_fw_w_helper,
	.register_dev =			mwifiex_register_dev,
	.unregister_dev =		mwifiex_unregister_dev,
	.enable_int =			mwifiex_pcie_enable_host_int,
	.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,
2833
	.init_fw_port =			mwifiex_pcie_init_fw_port,
2834
	.clean_pcie_ring =		mwifiex_clean_pcie_ring_buf,
2835
	.device_dump =			mwifiex_pcie_device_dump,
2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847
};

/*
 * 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 已提交
2848
	pr_debug("Marvell PCIe Driver\n");
2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880

	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;

2881
	cancel_work_sync(&pcie_work);
2882 2883 2884 2885 2886 2887 2888 2889 2890 2891
	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");
A
Avinash Patil 已提交
2892 2893
MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);
2894
MODULE_FIRMWARE(PCIE8997_DEFAULT_FW_NAME);