blob: 06aae55485e5aef2df60492ecfe74329f083ed9c [file] [log] [blame]
Amitkumar Karward930fae2011-10-11 17:41:21 -07001/*
2 * Marvell Wireless LAN device driver: PCIE specific handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/firmware.h>
21
22#include "decl.h"
23#include "ioctl.h"
24#include "util.h"
25#include "fw.h"
26#include "main.h"
27#include "wmm.h"
28#include "11n.h"
29#include "pcie.h"
30
31#define PCIE_VERSION "1.0"
32#define DRV_NAME "Marvell mwifiex PCIe"
33
34static u8 user_rmmod;
35
36static struct mwifiex_if_ops pcie_ops;
37
38static struct semaphore add_remove_card_sem;
39static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
40static int mwifiex_pcie_resume(struct pci_dev *pdev);
41
Avinash Patilfc331462013-01-03 21:21:30 -080042static int
43mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
44 int size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070045{
Avinash Patilfc331462013-01-03 21:21:30 -080046 struct pcie_service_card *card = adapter->card;
47 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -070048
Avinash Patilfc331462013-01-03 21:21:30 -080049 buf_pa = pci_map_single(card->dev, skb->data, size, flags);
50 if (pci_dma_mapping_error(card->dev, buf_pa)) {
51 dev_err(adapter->dev, "failed to map pci memory!\n");
52 return -1;
53 }
54 memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t));
55 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070056}
57
58/*
59 * This function reads sleep cookie and checks if FW is ready
60 */
61static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
62{
63 u32 *cookie_addr;
64 struct pcie_service_card *card = adapter->card;
65
Avinash Patilfc331462013-01-03 21:21:30 -080066 if (card->sleep_cookie_vbase) {
67 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070068 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
69 *cookie_addr);
70 if (*cookie_addr == FW_AWAKE_COOKIE)
71 return true;
72 }
73
74 return false;
75}
76
77/*
78 * This function probes an mwifiex device and registers it. It allocates
79 * the card structure, enables PCIE function number and initiates the
80 * device registration and initialization procedure by adding a logical
81 * interface.
82 */
83static int mwifiex_pcie_probe(struct pci_dev *pdev,
84 const struct pci_device_id *ent)
85{
86 struct pcie_service_card *card;
87
88 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -070089 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -070090
91 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +000092 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -070093 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -070094
95 card->dev = pdev;
96
Avinash Patildd04e6a2013-02-08 18:18:06 -080097 if (ent->driver_data) {
98 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
99 card->pcie.firmware = data->firmware;
100 card->pcie.reg = data->reg;
101 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
102 }
103
Amitkumar Karward930fae2011-10-11 17:41:21 -0700104 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
105 MWIFIEX_PCIE)) {
106 pr_err("%s failed\n", __func__);
107 kfree(card);
108 return -1;
109 }
110
111 return 0;
112}
113
114/*
115 * This function removes the interface and frees up the card structure.
116 */
117static void mwifiex_pcie_remove(struct pci_dev *pdev)
118{
119 struct pcie_service_card *card;
120 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700121 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700122 int i;
123
124 card = pci_get_drvdata(pdev);
125 if (!card)
126 return;
127
128 adapter = card->adapter;
129 if (!adapter || !adapter->priv_num)
130 return;
131
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700132 /* In case driver is removed when asynchronous FW load is in progress */
133 wait_for_completion(&adapter->fw_load);
134
Amitkumar Karward930fae2011-10-11 17:41:21 -0700135 if (user_rmmod) {
136#ifdef CONFIG_PM
137 if (adapter->is_suspended)
138 mwifiex_pcie_resume(pdev);
139#endif
140
141 for (i = 0; i < adapter->priv_num; i++)
142 if ((GET_BSS_ROLE(adapter->priv[i]) ==
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700143 MWIFIEX_BSS_ROLE_STA) &&
144 adapter->priv[i]->media_connected)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700145 mwifiex_deauthenticate(adapter->priv[i], NULL);
146
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700147 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700148
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700149 mwifiex_disable_auto_ds(priv);
150
151 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700152 }
153
154 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
155 kfree(card);
156}
157
158/*
159 * Kernel needs to suspend all functions separately. Therefore all
160 * registered functions must have drivers with suspend and resume
161 * methods. Failing that the kernel simply removes the whole card.
162 *
163 * If already not suspended, this function allocates and sends a host
164 * sleep activate request to the firmware and turns off the traffic.
165 */
166static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
167{
168 struct mwifiex_adapter *adapter;
169 struct pcie_service_card *card;
170 int hs_actived, i;
171
172 if (pdev) {
173 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
Avinash Patil83f0c6d2013-01-21 21:04:10 -0800174 if (!card || !card->adapter) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700175 pr_err("Card or adapter structure is not valid\n");
176 return 0;
177 }
178 } else {
179 pr_err("PCIE device is not specified\n");
180 return 0;
181 }
182
183 adapter = card->adapter;
184
185 hs_actived = mwifiex_enable_hs(adapter);
186
187 /* Indicate device suspended */
188 adapter->is_suspended = true;
189
190 for (i = 0; i < adapter->priv_num; i++)
191 netif_carrier_off(adapter->priv[i]->netdev);
192
193 return 0;
194}
195
196/*
197 * Kernel needs to suspend all functions separately. Therefore all
198 * registered functions must have drivers with suspend and resume
199 * methods. Failing that the kernel simply removes the whole card.
200 *
201 * If already not resumed, this function turns on the traffic and
202 * sends a host sleep cancel request to the firmware.
203 */
204static int mwifiex_pcie_resume(struct pci_dev *pdev)
205{
206 struct mwifiex_adapter *adapter;
207 struct pcie_service_card *card;
208 int i;
209
210 if (pdev) {
211 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
212 if (!card || !card->adapter) {
213 pr_err("Card or adapter structure is not valid\n");
214 return 0;
215 }
216 } else {
217 pr_err("PCIE device is not specified\n");
218 return 0;
219 }
220
221 adapter = card->adapter;
222
223 if (!adapter->is_suspended) {
224 dev_warn(adapter->dev, "Device already resumed\n");
225 return 0;
226 }
227
228 adapter->is_suspended = false;
229
230 for (i = 0; i < adapter->priv_num; i++)
231 if (adapter->priv[i]->media_connected)
232 netif_carrier_on(adapter->priv[i]->netdev);
233
234 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700235 MWIFIEX_ASYNC_CMD);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700236
237 return 0;
238}
239
240#define PCIE_VENDOR_ID_MARVELL (0x11ab)
241#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30)
242
243static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
244 {
245 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
246 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800247 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700248 },
249 {},
250};
251
252MODULE_DEVICE_TABLE(pci, mwifiex_ids);
253
254/* PCI Device Driver */
255static struct pci_driver __refdata mwifiex_pcie = {
256 .name = "mwifiex_pcie",
257 .id_table = mwifiex_ids,
258 .probe = mwifiex_pcie_probe,
259 .remove = mwifiex_pcie_remove,
260#ifdef CONFIG_PM
261 /* Power Management Hooks */
262 .suspend = mwifiex_pcie_suspend,
263 .resume = mwifiex_pcie_resume,
264#endif
265};
266
267/*
268 * This function writes data into PCIE card register.
269 */
270static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
271{
272 struct pcie_service_card *card = adapter->card;
273
274 iowrite32(data, card->pci_mmap1 + reg);
275
276 return 0;
277}
278
279/*
280 * This function reads data from PCIE card register.
281 */
282static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
283{
284 struct pcie_service_card *card = adapter->card;
285
286 *data = ioread32(card->pci_mmap1 + reg);
287
288 return 0;
289}
290
291/*
292 * This function wakes up the card.
293 *
294 * A host power up command is written to the card configuration
295 * register to wake up the card.
296 */
297static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
298{
299 int i = 0;
300
301 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
302 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700303 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700304 /* 50ms max wait */
305 if (i == 50000)
306 break;
307 }
308
309 dev_dbg(adapter->dev, "event: Wakeup device...\n");
310
311 /* Enable interrupts or any chip access will wakeup device */
312 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) {
313 dev_warn(adapter->dev, "Enable host interrupt failed\n");
314 return -1;
315 }
316
317 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
318 adapter->ps_state = PS_STATE_AWAKE;
319
320 return 0;
321}
322
323/*
324 * This function is called after the card has woken up.
325 *
326 * The card configuration register is reset.
327 */
328static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
329{
330 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
331
332 return 0;
333}
334
335/*
336 * This function disables the host interrupt.
337 *
338 * The host interrupt mask is read, the disable bit is reset and
339 * written back to the card host interrupt mask register.
340 */
341static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
342{
343 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
344 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
345 0x00000000)) {
346 dev_warn(adapter->dev, "Disable host interrupt failed\n");
347 return -1;
348 }
349 }
350
351 return 0;
352}
353
354/*
355 * This function enables the host interrupt.
356 *
357 * The host interrupt enable mask is written to the card
358 * host interrupt mask register.
359 */
360static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
361{
362 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
363 /* Simply write the mask to the register */
364 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
365 HOST_INTR_MASK)) {
366 dev_warn(adapter->dev, "Enable host interrupt failed\n");
367 return -1;
368 }
369 }
370
371 return 0;
372}
373
374/*
Avinash Patil07324842013-02-08 18:18:07 -0800375 * This function initializes TX buffer ring descriptors
376 */
377static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
378{
379 struct pcie_service_card *card = adapter->card;
380 struct mwifiex_pcie_buf_desc *desc;
381 int i;
382
383 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
384 card->tx_buf_list[i] = NULL;
385 card->txbd_ring[i] = (void *)(card->txbd_ring_vbase +
386 (sizeof(*desc) * i));
387 desc = card->txbd_ring[i];
388 memset(desc, 0, sizeof(*desc));
389 }
390
391 return 0;
392}
393
394/* This function initializes RX buffer ring descriptors. Each SKB is allocated
395 * here and after mapping PCI memory, its physical address is assigned to
396 * PCIE Rx buffer descriptor's physical address.
397 */
398static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
399{
400 struct pcie_service_card *card = adapter->card;
401 struct sk_buff *skb;
402 struct mwifiex_pcie_buf_desc *desc;
403 dma_addr_t buf_pa;
404 int i;
405
406 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
407 /* Allocate skb here so that firmware can DMA data from it */
408 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
409 if (!skb) {
410 dev_err(adapter->dev,
411 "Unable to allocate skb for RX ring.\n");
412 kfree(card->rxbd_ring_vbase);
413 return -ENOMEM;
414 }
415
416 if (mwifiex_map_pci_memory(adapter, skb,
417 MWIFIEX_RX_DATA_BUF_SIZE,
418 PCI_DMA_FROMDEVICE))
419 return -1;
420
421 MWIFIEX_SKB_PACB(skb, &buf_pa);
422
423 dev_dbg(adapter->dev,
424 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
425 skb, skb->len, skb->data, (u32)buf_pa,
426 (u32)((u64)buf_pa >> 32));
427
428 card->rx_buf_list[i] = skb;
429 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
430 (sizeof(*desc) * i));
431 desc = card->rxbd_ring[i];
432 desc->paddr = buf_pa;
433 desc->len = (u16)skb->len;
434 desc->flags = 0;
435 }
436
437 return 0;
438}
439
440/* This function initializes event buffer ring descriptors. Each SKB is
441 * allocated here and after mapping PCI memory, its physical address is assigned
442 * to PCIE Rx buffer descriptor's physical address
443 */
444static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
445{
446 struct pcie_service_card *card = adapter->card;
447 struct mwifiex_pcie_buf_desc *desc;
448 struct sk_buff *skb;
449 dma_addr_t buf_pa;
450 int i;
451
452 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
453 /* Allocate skb here so that firmware can DMA data from it */
454 skb = dev_alloc_skb(MAX_EVENT_SIZE);
455 if (!skb) {
456 dev_err(adapter->dev,
457 "Unable to allocate skb for EVENT buf.\n");
458 kfree(card->evtbd_ring_vbase);
459 return -ENOMEM;
460 }
461 skb_put(skb, MAX_EVENT_SIZE);
462
463 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
464 PCI_DMA_FROMDEVICE))
465 return -1;
466
467 MWIFIEX_SKB_PACB(skb, &buf_pa);
468
469 dev_dbg(adapter->dev,
470 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
471 skb, skb->len, skb->data, (u32)buf_pa,
472 (u32)((u64)buf_pa >> 32));
473
474 card->evt_buf_list[i] = skb;
475 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
476 (sizeof(*desc) * i));
477
478 desc = card->evtbd_ring[i];
479 desc->paddr = buf_pa;
480 desc->len = (u16)skb->len;
481 desc->flags = 0;
482 }
483
484 return 0;
485}
486
487/* This function cleans up TX buffer rings. If any of the buffer list has valid
488 * SKB address, associated SKB is freed.
489 */
490static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
491{
492 struct pcie_service_card *card = adapter->card;
493 struct sk_buff *skb;
494 struct mwifiex_pcie_buf_desc *desc;
495 int i;
496
497 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
498 desc = card->txbd_ring[i];
499 if (card->tx_buf_list[i]) {
500 skb = card->tx_buf_list[i];
501 pci_unmap_single(card->dev, desc->paddr, skb->len,
502 PCI_DMA_TODEVICE);
503 dev_kfree_skb_any(skb);
504 }
505 card->tx_buf_list[i] = NULL;
506 memset(desc, 0, sizeof(*desc));
507 }
508
509 return;
510}
511
512/* This function cleans up RX buffer rings. If any of the buffer list has valid
513 * SKB address, associated SKB is freed.
514 */
515static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
516{
517 struct pcie_service_card *card = adapter->card;
518 struct mwifiex_pcie_buf_desc *desc;
519 struct sk_buff *skb;
520 int i;
521
522 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
523 desc = card->rxbd_ring[i];
524 if (card->rx_buf_list[i]) {
525 skb = card->rx_buf_list[i];
526 pci_unmap_single(card->dev, desc->paddr,
527 MWIFIEX_RX_DATA_BUF_SIZE,
528 PCI_DMA_FROMDEVICE);
529 dev_kfree_skb_any(skb);
530 }
531 memset(desc, 0, sizeof(*desc));
532 }
533
534 return;
535}
536
537/* This function cleans up event buffer rings. If any of the buffer list has
538 * valid SKB address, associated SKB is freed.
539 */
540static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
541{
542 struct pcie_service_card *card = adapter->card;
543 struct mwifiex_pcie_buf_desc *desc;
544 struct sk_buff *skb;
545 int i;
546
547 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
548 desc = card->evtbd_ring[i];
549 if (card->evt_buf_list[i]) {
550 skb = card->evt_buf_list[i];
551 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE,
552 PCI_DMA_FROMDEVICE);
553 dev_kfree_skb_any(skb);
554 }
555 card->evt_buf_list[i] = NULL;
556 memset(desc, 0, sizeof(*desc));
557 }
558
559 return;
560}
561
562/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700563 */
564static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
565{
566 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800567 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700568
569 /*
570 * driver maintaines the write pointer and firmware maintaines the read
571 * pointer. The write pointer starts at 0 (zero) while the read pointer
572 * starts at zero with rollover bit set
573 */
574 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800575 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700576
577 /* allocate shared memory for the BD ring and divide the same in to
578 several descriptors */
579 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700580 MWIFIEX_MAX_TXRX_BD;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700581 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700582 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800583 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
584 card->txbd_ring_size,
585 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700586 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800587 dev_err(adapter->dev,
588 "allocate consistent memory (%d bytes) failed!\n",
589 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800590 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700591 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700592 dev_dbg(adapter->dev,
593 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800594 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700595 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700596
Avinash Patil07324842013-02-08 18:18:07 -0800597 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700598}
599
600static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
601{
602 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800603 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700604
Avinash Patil07324842013-02-08 18:18:07 -0800605 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700606
Avinash Patilfc331462013-01-03 21:21:30 -0800607 if (card->txbd_ring_vbase)
608 pci_free_consistent(card->dev, card->txbd_ring_size,
609 card->txbd_ring_vbase,
610 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700611 card->txbd_ring_size = 0;
612 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800613 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700614 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800615 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700616
617 return 0;
618}
619
620/*
621 * This function creates buffer descriptor ring for RX
622 */
623static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
624{
625 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800626 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700627
628 /*
629 * driver maintaines the read pointer and firmware maintaines the write
630 * pointer. The write pointer starts at 0 (zero) while the read pointer
631 * starts at zero with rollover bit set
632 */
633 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800634 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700635
636 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700637 MWIFIEX_MAX_TXRX_BD;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700638 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700639 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800640 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
641 card->rxbd_ring_size,
642 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700643 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800644 dev_err(adapter->dev,
645 "allocate consistent memory (%d bytes) failed!\n",
646 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800647 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700648 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700649
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700650 dev_dbg(adapter->dev,
651 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
652 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
653 (u32)((u64)card->rxbd_ring_pbase >> 32),
654 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700655
Avinash Patil07324842013-02-08 18:18:07 -0800656 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700657}
658
659/*
660 * This function deletes Buffer descriptor ring for RX
661 */
662static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
663{
664 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800665 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700666
Avinash Patil07324842013-02-08 18:18:07 -0800667 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700668
Avinash Patilfc331462013-01-03 21:21:30 -0800669 if (card->rxbd_ring_vbase)
670 pci_free_consistent(card->dev, card->rxbd_ring_size,
671 card->rxbd_ring_vbase,
672 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700673 card->rxbd_ring_size = 0;
674 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800675 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700676 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800677 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700678
679 return 0;
680}
681
682/*
683 * This function creates buffer descriptor ring for Events
684 */
685static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
686{
687 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800688 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700689
690 /*
691 * driver maintaines the read pointer and firmware maintaines the write
692 * pointer. The write pointer starts at 0 (zero) while the read pointer
693 * starts at zero with rollover bit set
694 */
695 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800696 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700697
698 card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700699 MWIFIEX_MAX_EVT_BD;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700700 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700701 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800702 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
703 card->evtbd_ring_size,
704 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700705 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700706 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800707 "allocate consistent memory (%d bytes) failed!\n",
708 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800709 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700710 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700711
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700712 dev_dbg(adapter->dev,
713 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
714 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
715 (u32)((u64)card->evtbd_ring_pbase >> 32),
716 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700717
Avinash Patil07324842013-02-08 18:18:07 -0800718 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700719}
720
721/*
722 * This function deletes Buffer descriptor ring for Events
723 */
724static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
725{
726 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800727 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700728
Avinash Patil07324842013-02-08 18:18:07 -0800729 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700730
Avinash Patilfc331462013-01-03 21:21:30 -0800731 if (card->evtbd_ring_vbase)
732 pci_free_consistent(card->dev, card->evtbd_ring_size,
733 card->evtbd_ring_vbase,
734 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700735 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800736 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700737 card->evtbd_ring_size = 0;
738 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800739 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700740
741 return 0;
742}
743
744/*
745 * This function allocates a buffer for CMDRSP
746 */
747static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
748{
749 struct pcie_service_card *card = adapter->card;
750 struct sk_buff *skb;
751
752 /* Allocate memory for receiving command response data */
753 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
754 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700755 dev_err(adapter->dev,
756 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700757 return -ENOMEM;
758 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700759 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800760 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
761 PCI_DMA_FROMDEVICE))
762 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700763
Avinash Patilfc331462013-01-03 21:21:30 -0800764 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700765
766 return 0;
767}
768
769/*
770 * This function deletes a buffer for CMDRSP
771 */
772static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
773{
774 struct pcie_service_card *card;
Avinash Patilfc331462013-01-03 21:21:30 -0800775 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700776
777 if (!adapter)
778 return 0;
779
780 card = adapter->card;
781
Avinash Patilfc331462013-01-03 21:21:30 -0800782 if (card && card->cmdrsp_buf) {
783 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
784 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
785 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700786 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800787 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700788
Avinash Patilfc331462013-01-03 21:21:30 -0800789 if (card && card->cmd_buf) {
790 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
791 pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER,
792 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700793 dev_kfree_skb_any(card->cmd_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800794 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700795 return 0;
796}
797
798/*
799 * This function allocates a buffer for sleep cookie
800 */
801static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
802{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700803 struct pcie_service_card *card = adapter->card;
804
Avinash Patilfc331462013-01-03 21:21:30 -0800805 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
806 &card->sleep_cookie_pbase);
807 if (!card->sleep_cookie_vbase) {
808 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700809 return -ENOMEM;
810 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700811 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800812 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700813
814 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800815 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700816
817 return 0;
818}
819
820/*
821 * This function deletes buffer for sleep cookie
822 */
823static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
824{
825 struct pcie_service_card *card;
826
827 if (!adapter)
828 return 0;
829
830 card = adapter->card;
831
Avinash Patilfc331462013-01-03 21:21:30 -0800832 if (card && card->sleep_cookie_vbase) {
833 pci_free_consistent(card->dev, sizeof(u32),
834 card->sleep_cookie_vbase,
835 card->sleep_cookie_pbase);
836 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700837 }
838
839 return 0;
840}
841
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800842/* This function flushes the TX buffer descriptor ring
843 * This function defined as handler is also called while cleaning TXRX
844 * during disconnect/ bss stop.
845 */
846static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
847{
848 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800849 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800850 u32 rdptr;
851
852 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800853 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800854 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800855 "Flush TXBD: failed to read reg->tx_rdptr\n");
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800856 return -1;
857 }
858
859 if (!mwifiex_pcie_txbd_empty(card, rdptr)) {
860 card->txbd_flush = 1;
861 /* write pointer already set at last send
862 * send dnld-rdy intr again, wait for completion.
863 */
864 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
865 CPU_INTR_DNLD_RDY)) {
866 dev_err(adapter->dev,
867 "failed to assert dnld-rdy interrupt.\n");
868 return -1;
869 }
870 }
871 return 0;
872}
873
Amitkumar Karward930fae2011-10-11 17:41:21 -0700874/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800875 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700876 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800877static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700878{
Avinash Patile7f767a2013-01-03 21:21:32 -0800879 const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD;
880 struct sk_buff *skb;
881 dma_addr_t buf_pa;
882 u32 wrdoneidx, rdptr, unmap_count = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700883 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800884 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700885
886 if (!mwifiex_pcie_ok_to_access_hw(adapter))
887 mwifiex_pm_wakeup_card(adapter);
888
889 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800890 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700891 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800892 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700893 return -1;
894 }
895
Avinash Patile7f767a2013-01-03 21:21:32 -0800896 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
897 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700898
Avinash Patile7f767a2013-01-03 21:21:32 -0800899 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800900 while (((card->txbd_rdptr & reg->tx_mask) !=
901 (rdptr & reg->tx_mask)) ||
902 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
903 (rdptr & reg->tx_rollover_ind))) {
904 wrdoneidx = card->txbd_rdptr & reg->tx_mask;
Avinash Patile7f767a2013-01-03 21:21:32 -0800905
906 skb = card->tx_buf_list[wrdoneidx];
907 if (skb) {
908 dev_dbg(adapter->dev,
909 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
910 skb, wrdoneidx);
911 MWIFIEX_SKB_PACB(skb, &buf_pa);
912 pci_unmap_single(card->dev, buf_pa, skb->len,
913 PCI_DMA_TODEVICE);
914
915 unmap_count++;
916
917 if (card->txbd_flush)
918 mwifiex_write_data_complete(adapter, skb, 0,
919 -1);
920 else
921 mwifiex_write_data_complete(adapter, skb, 0, 0);
922 }
923
924 card->tx_buf_list[wrdoneidx] = NULL;
925 card->txbd_ring[wrdoneidx]->paddr = 0;
Avinash Patil6ccea752013-01-22 16:29:03 -0800926 card->txbd_ring[wrdoneidx]->len = 0;
927 card->txbd_ring[wrdoneidx]->flags = 0;
Avinash Patile7f767a2013-01-03 21:21:32 -0800928 card->txbd_rdptr++;
929
Avinash Patildd04e6a2013-02-08 18:18:06 -0800930 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -0800931 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -0800932 reg->tx_rollover_ind) ^
933 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -0800934 }
935
936 if (unmap_count)
937 adapter->data_sent = false;
938
939 if (card->txbd_flush) {
Avinash Patildd04e6a2013-02-08 18:18:06 -0800940 if (((card->txbd_wrptr & reg->tx_mask) ==
941 (card->txbd_rdptr & reg->tx_mask)) &&
942 ((card->txbd_wrptr & reg->tx_rollover_ind) !=
943 (card->txbd_rdptr & reg->tx_rollover_ind)))
Avinash Patile7f767a2013-01-03 21:21:32 -0800944 card->txbd_flush = 0;
945 else
946 mwifiex_clean_pcie_ring_buf(adapter);
947 }
948
949 return 0;
950}
951
952/* This function sends data buffer to device. First 4 bytes of payload
953 * are filled with payload length and payload type. Then this payload
954 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
955 * Download ready interrupt to FW is deffered if Tx ring is not full and
956 * additional payload can be accomodated.
957 */
958static int
959mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
960 struct mwifiex_tx_param *tx_param)
961{
962 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800963 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patile7f767a2013-01-03 21:21:32 -0800964 u32 wrindx;
965 int ret;
966 dma_addr_t buf_pa;
967 __le16 *tmp;
968
969 if (!(skb->data && skb->len)) {
970 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
971 __func__, skb->data, skb->len);
972 return -1;
973 }
974
975 if (!mwifiex_pcie_ok_to_access_hw(adapter))
976 mwifiex_pm_wakeup_card(adapter);
977
978 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
979 card->txbd_rdptr, card->txbd_wrptr);
980 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700981 u8 *payload;
982
983 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -0800984 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700985 tmp = (__le16 *)&payload[0];
986 *tmp = cpu_to_le16((u16)skb->len);
987 tmp = (__le16 *)&payload[2];
988 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -0800989
990 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
991 PCI_DMA_TODEVICE))
992 return -1;
993
Avinash Patildd04e6a2013-02-08 18:18:06 -0800994 wrindx = card->txbd_wrptr & reg->tx_mask;
Avinash Patile7f767a2013-01-03 21:21:32 -0800995 MWIFIEX_SKB_PACB(skb, &buf_pa);
996 card->tx_buf_list[wrindx] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -0800997 card->txbd_ring[wrindx]->paddr = buf_pa;
Avinash Patile7f767a2013-01-03 21:21:32 -0800998 card->txbd_ring[wrindx]->len = (u16)skb->len;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700999 card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1000 MWIFIEX_BD_FLAG_LAST_DESC;
1001
Avinash Patildd04e6a2013-02-08 18:18:06 -08001002 if ((++card->txbd_wrptr & reg->tx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001003 MWIFIEX_MAX_TXRX_BD)
1004 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001005 reg->tx_rollover_ind) ^
1006 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001007
Avinash Patildd04e6a2013-02-08 18:18:06 -08001008 /* Write the TX ring write pointer in to reg->tx_wrptr */
1009 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001010 card->txbd_wrptr)) {
1011 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001012 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001013 ret = -1;
1014 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001015 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001016 if ((mwifiex_pcie_txbd_not_full(card)) &&
1017 tx_param->next_pkt_len) {
1018 /* have more packets and TxBD still can hold more */
1019 dev_dbg(adapter->dev,
1020 "SEND DATA: delay dnld-rdy interrupt.\n");
1021 adapter->data_sent = false;
1022 } else {
1023 /* Send the TX ready interrupt */
1024 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1025 CPU_INTR_DNLD_RDY)) {
1026 dev_err(adapter->dev,
1027 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1028 ret = -1;
1029 goto done_unmap;
1030 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001031 }
1032 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001033 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001034 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001035 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001036 dev_dbg(adapter->dev,
1037 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001038 adapter->data_sent = true;
1039 /* Send the TX ready interrupt */
1040 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1041 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001042 dev_err(adapter->dev,
1043 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001044 return -EBUSY;
1045 }
1046
Avinash Patile7f767a2013-01-03 21:21:32 -08001047 return -EINPROGRESS;
1048done_unmap:
1049 MWIFIEX_SKB_PACB(skb, &buf_pa);
1050 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1051 card->tx_buf_list[wrindx] = NULL;
1052 card->txbd_ring[wrindx]->paddr = 0;
1053 card->txbd_ring[wrindx]->len = 0;
1054 card->txbd_ring[wrindx]->flags = 0;
1055 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001056}
1057
1058/*
1059 * This function handles received buffer ring and
1060 * dispatches packets to upper
1061 */
1062static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1063{
1064 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001065 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001066 u32 wrptr, rd_index;
Avinash Patile7f767a2013-01-03 21:21:32 -08001067 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001068 int ret = 0;
1069 struct sk_buff *skb_tmp = NULL;
1070
Avinash Patile7f767a2013-01-03 21:21:32 -08001071 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1072 mwifiex_pm_wakeup_card(adapter);
1073
Amitkumar Karward930fae2011-10-11 17:41:21 -07001074 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001075 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001076 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001077 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001078 ret = -1;
1079 goto done;
1080 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001081 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001082
Avinash Patildd04e6a2013-02-08 18:18:06 -08001083 while (((wrptr & reg->rx_mask) !=
1084 (card->rxbd_rdptr & reg->rx_mask)) ||
1085 ((wrptr & reg->rx_rollover_ind) ==
1086 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001087 struct sk_buff *skb_data;
1088 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001089 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001090
Avinash Patildd04e6a2013-02-08 18:18:06 -08001091 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001092 skb_data = card->rx_buf_list[rd_index];
1093
Avinash Patile7f767a2013-01-03 21:21:32 -08001094 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1095 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1096 PCI_DMA_FROMDEVICE);
1097 card->rx_buf_list[rd_index] = NULL;
1098
Amitkumar Karward930fae2011-10-11 17:41:21 -07001099 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001100 * first 2 bytes for len, next 2 bytes is for type
1101 */
1102 pkt_len = *((__le16 *)skb_data->data);
1103 rx_len = le16_to_cpu(pkt_len);
1104 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001105 dev_dbg(adapter->dev,
1106 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1107 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001108 skb_pull(skb_data, INTF_HEADER_LEN);
1109 mwifiex_handle_rx_packet(adapter, skb_data);
1110
1111 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001112 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001113 dev_err(adapter->dev,
1114 "Unable to allocate skb.\n");
1115 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001116 }
1117
Avinash Patile7f767a2013-01-03 21:21:32 -08001118 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1119 MWIFIEX_RX_DATA_BUF_SIZE,
1120 PCI_DMA_FROMDEVICE))
1121 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001122
Avinash Patile7f767a2013-01-03 21:21:32 -08001123 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1124
1125 dev_dbg(adapter->dev,
1126 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1127 skb_tmp, rd_index);
1128 card->rx_buf_list[rd_index] = skb_tmp;
1129 card->rxbd_ring[rd_index]->paddr = buf_pa;
1130 card->rxbd_ring[rd_index]->len = skb_tmp->len;
1131 card->rxbd_ring[rd_index]->flags = 0;
1132
Avinash Patildd04e6a2013-02-08 18:18:06 -08001133 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001134 MWIFIEX_MAX_TXRX_BD) {
1135 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001136 reg->rx_rollover_ind) ^
1137 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001138 }
1139 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001140 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001141
Avinash Patildd04e6a2013-02-08 18:18:06 -08001142 /* Write the RX ring read pointer in to reg->rx_rdptr */
1143 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001144 card->rxbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001145 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001146 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001147 ret = -1;
1148 goto done;
1149 }
1150
1151 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001152 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001153 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001154 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001155 ret = -1;
1156 goto done;
1157 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001158 dev_dbg(adapter->dev,
1159 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001160 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001161 }
1162
1163done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001164 return ret;
1165}
1166
1167/*
1168 * This function downloads the boot command to device
1169 */
1170static int
1171mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1172{
Avinash Patilfc331462013-01-03 21:21:30 -08001173 dma_addr_t buf_pa;
1174 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001175 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001176
Avinash Patilfc331462013-01-03 21:21:30 -08001177 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001178 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001179 "Invalid parameter in %s <%p. len %d>\n",
1180 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001181 return -1;
1182 }
1183
Avinash Patilfc331462013-01-03 21:21:30 -08001184 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1185 return -1;
1186
1187 MWIFIEX_SKB_PACB(skb, &buf_pa);
1188
Avinash Patildd04e6a2013-02-08 18:18:06 -08001189 /* Write the lower 32bits of the physical address to low command
1190 * address scratch register
1191 */
1192 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001193 dev_err(adapter->dev,
1194 "%s: failed to write download command to boot code.\n",
1195 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001196 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1197 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001198 return -1;
1199 }
1200
Avinash Patildd04e6a2013-02-08 18:18:06 -08001201 /* Write the upper 32bits of the physical address to high command
1202 * address scratch register
1203 */
1204 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001205 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001206 dev_err(adapter->dev,
1207 "%s: failed to write download command to boot code.\n",
1208 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001209 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1210 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001211 return -1;
1212 }
1213
Avinash Patildd04e6a2013-02-08 18:18:06 -08001214 /* Write the command length to cmd_size scratch register */
1215 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001216 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001217 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001218 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001219 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1220 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001221 return -1;
1222 }
1223
1224 /* Ring the door bell */
1225 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1226 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001227 dev_err(adapter->dev,
1228 "%s: failed to assert door-bell intr\n", __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001229 pci_unmap_single(card->dev, buf_pa,
1230 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001231 return -1;
1232 }
1233
1234 return 0;
1235}
1236
Avinash Patilc6d1d872013-01-03 21:21:29 -08001237/* This function init rx port in firmware which in turn enables to receive data
1238 * from device before transmitting any packet.
1239 */
1240static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1241{
1242 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001243 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001244
Avinash Patildd04e6a2013-02-08 18:18:06 -08001245 /* Write the RX ring read pointer in to reg->rx_rdptr */
1246 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001247 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001248 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001249 return -1;
1250 }
1251 return 0;
1252}
1253
1254/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001255 */
1256static int
1257mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1258{
1259 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001260 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001261 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001262 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1263 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001264
1265 if (!(skb->data && skb->len)) {
1266 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001267 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001268 return -1;
1269 }
1270
1271 /* Make sure a command response buffer is available */
1272 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001273 dev_err(adapter->dev,
1274 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001275 return -EBUSY;
1276 }
1277
Avinash Patilfc331462013-01-03 21:21:30 -08001278 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1279 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001280
1281 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001282
1283 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1284 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1285
1286 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1287 return -1;
1288
1289 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001290
1291 /* To send a command, the driver will:
1292 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001293 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001294 2. Ring the door bell (i.e. set the door bell interrupt)
1295
1296 In response to door bell interrupt, the firmware will perform
1297 the DMA of the command packet (first header to obtain the total
1298 length and then rest of the command).
1299 */
1300
1301 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001302 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001303 /* Write the lower 32bits of the cmdrsp buffer physical
1304 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001305 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001306 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001307 dev_err(adapter->dev,
1308 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001309 ret = -1;
1310 goto done;
1311 }
1312 /* Write the upper 32bits of the cmdrsp buffer physical
1313 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001314 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001315 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001316 dev_err(adapter->dev,
1317 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001318 ret = -1;
1319 goto done;
1320 }
1321 }
1322
Avinash Patilfc331462013-01-03 21:21:30 -08001323 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001324 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1325 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1326 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001327 dev_err(adapter->dev,
1328 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001329 ret = -1;
1330 goto done;
1331 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001332 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1333 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001334 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001335 dev_err(adapter->dev,
1336 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001337 ret = -1;
1338 goto done;
1339 }
1340
Avinash Patildd04e6a2013-02-08 18:18:06 -08001341 /* Write the command length to reg->cmd_size */
1342 if (mwifiex_write_reg(adapter, reg->cmd_size,
1343 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001344 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001345 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001346 ret = -1;
1347 goto done;
1348 }
1349
1350 /* Ring the door bell */
1351 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1352 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001353 dev_err(adapter->dev,
1354 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001355 ret = -1;
1356 goto done;
1357 }
1358
1359done:
1360 if (ret)
1361 adapter->cmd_sent = false;
1362
1363 return 0;
1364}
1365
1366/*
1367 * This function handles command complete interrupt
1368 */
1369static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1370{
1371 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001372 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001373 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001374 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001375 u16 rx_len;
1376 __le16 pkt_len;
1377 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001378
1379 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1380
Avinash Patilfc331462013-01-03 21:21:30 -08001381 MWIFIEX_SKB_PACB(skb, &buf_pa);
1382 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1383 PCI_DMA_FROMDEVICE);
1384
1385 pkt_len = *((__le16 *)skb->data);
1386 rx_len = le16_to_cpu(pkt_len);
1387 skb_trim(skb, rx_len);
1388 skb_pull(skb, INTF_HEADER_LEN);
1389
Amitkumar Karward930fae2011-10-11 17:41:21 -07001390 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001391 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001392 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1393 skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001394 while (mwifiex_pcie_ok_to_access_hw(adapter) &&
1395 (count++ < 10))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001396 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001397 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001398 dev_err(adapter->dev,
1399 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001400 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001401 memcpy(adapter->upld_buf, skb->data,
1402 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patilfc331462013-01-03 21:21:30 -08001403 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1404 PCI_DMA_FROMDEVICE))
1405 return -1;
1406
1407 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001408 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001409 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001410 adapter->cmd_resp_received = true;
1411 /* Take the pointer and set it to CMD node and will
1412 return in the response complete callback */
1413 card->cmdrsp_buf = NULL;
1414
1415 /* Clear the cmd-rsp buffer address in scratch registers. This
1416 will prevent firmware from writing to the same response
1417 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001418 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001419 dev_err(adapter->dev,
1420 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001421 return -1;
1422 }
1423 /* Write the upper 32bits of the cmdrsp buffer physical
1424 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001425 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001426 dev_err(adapter->dev,
1427 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001428 return -1;
1429 }
1430 }
1431
1432 return 0;
1433}
1434
1435/*
1436 * Command Response processing complete handler
1437 */
1438static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1439 struct sk_buff *skb)
1440{
1441 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001442 dma_addr_t buf_pa;
1443 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001444
1445 if (skb) {
1446 card->cmdrsp_buf = skb;
1447 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001448 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1449 PCI_DMA_FROMDEVICE))
1450 return -1;
1451 }
1452
1453 skb_tmp = card->cmd_buf;
1454 if (skb_tmp) {
1455 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1456 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1457 PCI_DMA_FROMDEVICE);
1458 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001459 }
1460
1461 return 0;
1462}
1463
1464/*
1465 * This function handles firmware event ready interrupt
1466 */
1467static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1468{
1469 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001470 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001471 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1472 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001473 dma_addr_t buf_pa;
1474
1475 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1476 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001477
1478 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001479 dev_dbg(adapter->dev, "info: Event being processed, "
1480 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001481 return 0;
1482 }
1483
1484 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1485 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1486 return -1;
1487 }
1488
1489 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001490 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001491 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001492 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001493 return -1;
1494 }
1495
1496 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001497 card->evtbd_rdptr, wrptr);
1498 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1499 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001500 ((wrptr & reg->evt_rollover_ind) ==
1501 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001502 struct sk_buff *skb_cmd;
1503 __le16 data_len = 0;
1504 u16 evt_len;
1505
1506 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1507 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001508 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1509 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1510 PCI_DMA_FROMDEVICE);
1511
Amitkumar Karward930fae2011-10-11 17:41:21 -07001512 /* Take the pointer and set it to event pointer in adapter
1513 and will return back after event handling callback */
1514 card->evt_buf_list[rdptr] = NULL;
1515 card->evtbd_ring[rdptr]->paddr = 0;
1516 card->evtbd_ring[rdptr]->len = 0;
1517 card->evtbd_ring[rdptr]->flags = 0;
1518
1519 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1520 adapter->event_cause = event;
1521 /* The first 4bytes will be the event transfer header
1522 len is 2 bytes followed by type which is 2 bytes */
1523 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1524 evt_len = le16_to_cpu(data_len);
1525
1526 skb_pull(skb_cmd, INTF_HEADER_LEN);
1527 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1528
1529 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1530 memcpy(adapter->event_body, skb_cmd->data +
1531 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1532 MWIFIEX_EVENT_HEADER_LEN);
1533
1534 adapter->event_received = true;
1535 adapter->event_skb = skb_cmd;
1536
1537 /* Do not update the event read pointer here, wait till the
1538 buffer is released. This is just to make things simpler,
1539 we need to find a better method of managing these buffers.
1540 */
1541 }
1542
1543 return 0;
1544}
1545
1546/*
1547 * Event processing complete handler
1548 */
1549static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1550 struct sk_buff *skb)
1551{
1552 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001553 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001554 int ret = 0;
1555 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1556 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001557 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001558
1559 if (!skb)
1560 return 0;
1561
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001562 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001563 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001564 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001565 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001566 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001567
1568 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001569 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001570 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001571 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001572 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001573 }
1574
1575 if (!card->evt_buf_list[rdptr]) {
1576 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001577 if (mwifiex_map_pci_memory(adapter, skb,
1578 MAX_EVENT_SIZE,
1579 PCI_DMA_FROMDEVICE))
1580 return -1;
1581 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001582 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001583 MWIFIEX_SKB_PACB(skb, &buf_pa);
1584 card->evtbd_ring[rdptr]->paddr = buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001585 card->evtbd_ring[rdptr]->len = (u16)skb->len;
1586 card->evtbd_ring[rdptr]->flags = 0;
1587 skb = NULL;
1588 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001589 dev_dbg(adapter->dev,
1590 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1591 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001592 }
1593
1594 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1595 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001596 reg->evt_rollover_ind) ^
1597 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001598 }
1599
1600 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001601 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001602
Avinash Patildd04e6a2013-02-08 18:18:06 -08001603 /* Write the event ring read pointer in to reg->evt_rdptr */
1604 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1605 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001606 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001607 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001608 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001609 }
1610
Amitkumar Karward930fae2011-10-11 17:41:21 -07001611 dev_dbg(adapter->dev, "info: Check Events Again\n");
1612 ret = mwifiex_pcie_process_event_ready(adapter);
1613
1614 return ret;
1615}
1616
1617/*
1618 * This function downloads the firmware to the card.
1619 *
1620 * Firmware is downloaded to the card in blocks. Every block download
1621 * is tested for CRC errors, and retried a number of times before
1622 * returning failure.
1623 */
1624static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1625 struct mwifiex_fw_image *fw)
1626{
1627 int ret;
1628 u8 *firmware = fw->fw_buf;
1629 u32 firmware_len = fw->fw_len;
1630 u32 offset = 0;
1631 struct sk_buff *skb;
1632 u32 txlen, tx_blocks = 0, tries, len;
1633 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001634 dma_addr_t buf_pa;
1635 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001636 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001637
1638 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001639 dev_err(adapter->dev,
1640 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001641 return -1;
1642 }
1643
1644 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001645 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001646
1647 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001648 dev_err(adapter->dev,
1649 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001650 return -1;
1651 }
1652
1653 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1654 if (!skb) {
1655 ret = -ENOMEM;
1656 goto done;
1657 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001658
1659 /* Perform firmware data transfer */
1660 do {
1661 u32 ireg_intr = 0;
1662
1663 /* More data? */
1664 if (offset >= firmware_len)
1665 break;
1666
1667 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001668 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001669 &len);
1670 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001671 dev_warn(adapter->dev,
1672 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001673 goto done;
1674 }
1675 if (len)
1676 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001677 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001678 }
1679
1680 if (!len) {
1681 break;
1682 } else if (len > MWIFIEX_UPLD_SIZE) {
1683 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001684 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001685 ret = -1;
1686 goto done;
1687 }
1688
1689 txlen = len;
1690
1691 if (len & BIT(0)) {
1692 block_retry_cnt++;
1693 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1694 pr_err("FW download failure @ %d, over max "
1695 "retry count\n", offset);
1696 ret = -1;
1697 goto done;
1698 }
1699 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001700 "helper: len = 0x%04X, txlen = %d\n",
1701 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001702 len &= ~BIT(0);
1703 /* Setting this to 0 to resend from same offset */
1704 txlen = 0;
1705 } else {
1706 block_retry_cnt = 0;
1707 /* Set blocksize to transfer - checking for
1708 last block */
1709 if (firmware_len - offset < txlen)
1710 txlen = firmware_len - offset;
1711
1712 dev_dbg(adapter->dev, ".");
1713
Avinash Patildd04e6a2013-02-08 18:18:06 -08001714 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1715 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001716
1717 /* Copy payload to buffer */
1718 memmove(skb->data, &firmware[offset], txlen);
1719 }
1720
1721 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001722 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001723
1724 /* Send the boot command to device */
1725 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001726 dev_err(adapter->dev,
1727 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001728 ret = -1;
1729 goto done;
1730 }
Avinash Patilfc331462013-01-03 21:21:30 -08001731
1732 MWIFIEX_SKB_PACB(skb, &buf_pa);
1733
Amitkumar Karward930fae2011-10-11 17:41:21 -07001734 /* Wait for the command done interrupt */
1735 do {
1736 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1737 &ireg_intr)) {
1738 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001739 "interrupt status during fw dnld.\n",
1740 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001741 pci_unmap_single(card->dev, buf_pa, skb->len,
1742 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001743 ret = -1;
1744 goto done;
1745 }
1746 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1747 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001748
1749 pci_unmap_single(card->dev, buf_pa, skb->len,
1750 PCI_DMA_TODEVICE);
1751
Amitkumar Karward930fae2011-10-11 17:41:21 -07001752 offset += txlen;
1753 } while (true);
1754
1755 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001756 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001757
1758 ret = 0;
1759
1760done:
1761 dev_kfree_skb_any(skb);
1762 return ret;
1763}
1764
1765/*
1766 * This function checks the firmware status in card.
1767 *
1768 * The winner interface is also determined by this function.
1769 */
1770static int
1771mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1772{
1773 int ret = 0;
1774 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001775 struct pcie_service_card *card = adapter->card;
1776 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001777 u32 tries;
1778
1779 /* Mask spurios interrupts */
1780 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001781 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001782 dev_warn(adapter->dev, "Write register failed\n");
1783 return -1;
1784 }
1785
1786 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001787 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1788 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001789 dev_err(adapter->dev,
1790 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001791 return -1;
1792 }
1793
1794 /* Wait for firmware initialization event */
1795 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001796 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001797 &firmware_stat))
1798 ret = -1;
1799 else
1800 ret = 0;
1801 if (ret)
1802 continue;
1803 if (firmware_stat == FIRMWARE_READY_PCIE) {
1804 ret = 0;
1805 break;
1806 } else {
1807 mdelay(100);
1808 ret = -1;
1809 }
1810 }
1811
1812 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001813 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001814 &winner_status))
1815 ret = -1;
1816 else if (!winner_status) {
1817 dev_err(adapter->dev, "PCI-E is the winner\n");
1818 adapter->winner = 1;
1819 ret = -1;
1820 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001821 dev_err(adapter->dev,
1822 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1823 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001824 ret = 0;
1825 }
1826 }
1827
1828 return ret;
1829}
1830
1831/*
1832 * This function reads the interrupt status from card.
1833 */
1834static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1835{
1836 u32 pcie_ireg;
1837 unsigned long flags;
1838
1839 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1840 return;
1841
1842 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1843 dev_warn(adapter->dev, "Read register failed\n");
1844 return;
1845 }
1846
1847 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1848
1849 mwifiex_pcie_disable_host_int(adapter);
1850
1851 /* Clear the pending interrupts */
1852 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1853 ~pcie_ireg)) {
1854 dev_warn(adapter->dev, "Write register failed\n");
1855 return;
1856 }
1857 spin_lock_irqsave(&adapter->int_lock, flags);
1858 adapter->int_status |= pcie_ireg;
1859 spin_unlock_irqrestore(&adapter->int_lock, flags);
1860
1861 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1862 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1863 (adapter->ps_state == PS_STATE_SLEEP)) {
1864 mwifiex_pcie_enable_host_int(adapter);
1865 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001866 PCIE_CPU_INT_EVENT,
1867 CPU_INTR_SLEEP_CFM_DONE)
1868 ) {
1869 dev_warn(adapter->dev,
1870 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001871 return;
1872
1873 }
1874 }
1875 } else if (!adapter->pps_uapsd_mode &&
1876 adapter->ps_state == PS_STATE_SLEEP) {
1877 /* Potentially for PCIe we could get other
1878 * interrupts like shared. Don't change power
1879 * state until cookie is set */
1880 if (mwifiex_pcie_ok_to_access_hw(adapter))
1881 adapter->ps_state = PS_STATE_AWAKE;
1882 }
1883 }
1884}
1885
1886/*
1887 * Interrupt handler for PCIe root port
1888 *
1889 * This function reads the interrupt status from firmware and assigns
1890 * the main process in workqueue which will handle the interrupt.
1891 */
1892static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
1893{
1894 struct pci_dev *pdev = (struct pci_dev *)context;
1895 struct pcie_service_card *card;
1896 struct mwifiex_adapter *adapter;
1897
1898 if (!pdev) {
1899 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
1900 goto exit;
1901 }
1902
1903 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
1904 if (!card || !card->adapter) {
1905 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001906 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001907 goto exit;
1908 }
1909 adapter = card->adapter;
1910
1911 if (adapter->surprise_removed)
1912 goto exit;
1913
1914 mwifiex_interrupt_status(adapter);
1915 queue_work(adapter->workqueue, &adapter->main_work);
1916
1917exit:
1918 return IRQ_HANDLED;
1919}
1920
1921/*
1922 * This function checks the current interrupt status.
1923 *
1924 * The following interrupts are checked and handled by this function -
1925 * - Data sent
1926 * - Command sent
1927 * - Command received
1928 * - Packets received
1929 * - Events received
1930 *
1931 * In case of Rx packets received, the packets are uploaded from card to
1932 * host and processed accordingly.
1933 */
1934static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1935{
1936 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08001937 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001938 unsigned long flags;
1939
1940 spin_lock_irqsave(&adapter->int_lock, flags);
1941 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08001942 pcie_ireg = adapter->int_status;
1943 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001944 spin_unlock_irqrestore(&adapter->int_lock, flags);
1945
Avinash Patil659c4782013-01-03 21:21:28 -08001946 while (pcie_ireg & HOST_INTR_MASK) {
1947 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
1948 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08001949 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
1950 ret = mwifiex_pcie_send_data_complete(adapter);
1951 if (ret)
1952 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001953 }
Avinash Patil659c4782013-01-03 21:21:28 -08001954 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
1955 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001956 dev_dbg(adapter->dev, "info: Rx DATA\n");
1957 ret = mwifiex_pcie_process_recv_data(adapter);
1958 if (ret)
1959 return ret;
1960 }
Avinash Patil659c4782013-01-03 21:21:28 -08001961 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
1962 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001963 dev_dbg(adapter->dev, "info: Rx EVENT\n");
1964 ret = mwifiex_pcie_process_event_ready(adapter);
1965 if (ret)
1966 return ret;
1967 }
1968
Avinash Patil659c4782013-01-03 21:21:28 -08001969 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1970 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001971 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001972 dev_dbg(adapter->dev,
1973 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001974 adapter->cmd_sent = false;
1975 }
1976 /* Handle command response */
1977 ret = mwifiex_pcie_process_cmd_complete(adapter);
1978 if (ret)
1979 return ret;
1980 }
1981
1982 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1983 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
1984 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001985 dev_warn(adapter->dev,
1986 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001987 return -1;
1988 }
1989
1990 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1991 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001992 PCIE_HOST_INT_STATUS,
1993 ~pcie_ireg)) {
1994 dev_warn(adapter->dev,
1995 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001996 return -1;
1997 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001998 }
1999
2000 }
2001 }
2002 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002003 adapter->cmd_sent, adapter->data_sent);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002004 mwifiex_pcie_enable_host_int(adapter);
2005
2006 return 0;
2007}
2008
2009/*
2010 * This function downloads data from driver to card.
2011 *
2012 * Both commands and data packets are transferred to the card by this
2013 * function.
2014 *
2015 * This function adds the PCIE specific header to the front of the buffer
2016 * before transferring. The header contains the length of the packet and
2017 * the type. The firmware handles the packets based upon this set type.
2018 */
2019static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2020 struct sk_buff *skb,
2021 struct mwifiex_tx_param *tx_param)
2022{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002023 if (!skb) {
2024 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002025 return -1;
2026 }
2027
2028 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002029 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002030 else if (type == MWIFIEX_TYPE_CMD)
2031 return mwifiex_pcie_send_cmd(adapter, skb);
2032
2033 return 0;
2034}
2035
2036/*
2037 * This function initializes the PCI-E host memory space, WCB rings, etc.
2038 *
2039 * The following initializations steps are followed -
2040 * - Allocate TXBD ring buffers
2041 * - Allocate RXBD ring buffers
2042 * - Allocate event BD ring buffers
2043 * - Allocate command response ring buffer
2044 * - Allocate sleep cookie buffer
2045 */
2046static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2047{
2048 struct pcie_service_card *card = adapter->card;
2049 int ret;
2050 struct pci_dev *pdev = card->dev;
2051
2052 pci_set_drvdata(pdev, card);
2053
2054 ret = pci_enable_device(pdev);
2055 if (ret)
2056 goto err_enable_dev;
2057
2058 pci_set_master(pdev);
2059
2060 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2061 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2062 if (ret) {
2063 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2064 goto err_set_dma_mask;
2065 }
2066
2067 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2068 if (ret) {
2069 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2070 goto err_set_dma_mask;
2071 }
2072
2073 ret = pci_request_region(pdev, 0, DRV_NAME);
2074 if (ret) {
2075 dev_err(adapter->dev, "req_reg(0) error\n");
2076 goto err_req_region0;
2077 }
2078 card->pci_mmap = pci_iomap(pdev, 0, 0);
2079 if (!card->pci_mmap) {
2080 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002081 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002082 goto err_iomap0;
2083 }
2084 ret = pci_request_region(pdev, 2, DRV_NAME);
2085 if (ret) {
2086 dev_err(adapter->dev, "req_reg(2) error\n");
2087 goto err_req_region2;
2088 }
2089 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2090 if (!card->pci_mmap1) {
2091 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002092 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002093 goto err_iomap2;
2094 }
2095
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002096 dev_dbg(adapter->dev,
2097 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2098 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002099
2100 card->cmdrsp_buf = NULL;
2101 ret = mwifiex_pcie_create_txbd_ring(adapter);
2102 if (ret)
2103 goto err_cre_txbd;
2104 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2105 if (ret)
2106 goto err_cre_rxbd;
2107 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2108 if (ret)
2109 goto err_cre_evtbd;
2110 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2111 if (ret)
2112 goto err_alloc_cmdbuf;
2113 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2114 if (ret)
2115 goto err_alloc_cookie;
2116
2117 return ret;
2118
2119err_alloc_cookie:
2120 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2121err_alloc_cmdbuf:
2122 mwifiex_pcie_delete_evtbd_ring(adapter);
2123err_cre_evtbd:
2124 mwifiex_pcie_delete_rxbd_ring(adapter);
2125err_cre_rxbd:
2126 mwifiex_pcie_delete_txbd_ring(adapter);
2127err_cre_txbd:
2128 pci_iounmap(pdev, card->pci_mmap1);
2129err_iomap2:
2130 pci_release_region(pdev, 2);
2131err_req_region2:
2132 pci_iounmap(pdev, card->pci_mmap);
2133err_iomap0:
2134 pci_release_region(pdev, 0);
2135err_req_region0:
2136err_set_dma_mask:
2137 pci_disable_device(pdev);
2138err_enable_dev:
2139 pci_set_drvdata(pdev, NULL);
2140 return ret;
2141}
2142
2143/*
2144 * This function cleans up the allocated card buffers.
2145 *
2146 * The following are freed by this function -
2147 * - TXBD ring buffers
2148 * - RXBD ring buffers
2149 * - Event BD ring buffers
2150 * - Command response ring buffer
2151 * - Sleep cookie buffer
2152 */
2153static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2154{
2155 struct pcie_service_card *card = adapter->card;
2156 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002157 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002158
Amitkumar Karward930fae2011-10-11 17:41:21 -07002159 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002160 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002161 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002162 dev_err(adapter->dev,
2163 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002164 }
2165
2166 if (pdev) {
2167 pci_iounmap(pdev, card->pci_mmap);
2168 pci_iounmap(pdev, card->pci_mmap1);
2169
2170 pci_release_regions(pdev);
2171 pci_disable_device(pdev);
2172 pci_set_drvdata(pdev, NULL);
2173 }
2174}
2175
2176/*
2177 * This function registers the PCIE device.
2178 *
2179 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2180 */
2181static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2182{
2183 int ret;
2184 struct pcie_service_card *card = adapter->card;
2185 struct pci_dev *pdev = card->dev;
2186
2187 /* save adapter pointer in card */
2188 card->adapter = adapter;
2189
2190 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2191 "MRVL_PCIE", pdev);
2192 if (ret) {
2193 pr_err("request_irq failed: ret=%d\n", ret);
2194 adapter->card = NULL;
2195 return -1;
2196 }
2197
2198 adapter->dev = &pdev->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002199 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002200
2201 return 0;
2202}
2203
2204/*
2205 * This function unregisters the PCIE device.
2206 *
2207 * The PCIE IRQ is released, the function is disabled and driver
2208 * data is set to null.
2209 */
2210static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2211{
2212 struct pcie_service_card *card = adapter->card;
2213
2214 if (card) {
2215 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2216 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002217
2218 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2219 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2220 mwifiex_pcie_delete_evtbd_ring(adapter);
2221 mwifiex_pcie_delete_rxbd_ring(adapter);
2222 mwifiex_pcie_delete_txbd_ring(adapter);
2223 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002224 }
2225}
2226
2227static struct mwifiex_if_ops pcie_ops = {
2228 .init_if = mwifiex_pcie_init,
2229 .cleanup_if = mwifiex_pcie_cleanup,
2230 .check_fw_status = mwifiex_check_fw_status,
2231 .prog_fw = mwifiex_prog_fw_w_helper,
2232 .register_dev = mwifiex_register_dev,
2233 .unregister_dev = mwifiex_unregister_dev,
2234 .enable_int = mwifiex_pcie_enable_host_int,
2235 .process_int_status = mwifiex_process_int_status,
2236 .host_to_card = mwifiex_pcie_host_to_card,
2237 .wakeup = mwifiex_pm_wakeup_card,
2238 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2239
2240 /* PCIE specific */
2241 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2242 .event_complete = mwifiex_pcie_event_complete,
2243 .update_mp_end_port = NULL,
2244 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002245 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002246 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002247};
2248
2249/*
2250 * This function initializes the PCIE driver module.
2251 *
2252 * This initiates the semaphore and registers the device with
2253 * PCIE bus.
2254 */
2255static int mwifiex_pcie_init_module(void)
2256{
2257 int ret;
2258
2259 pr_debug("Marvell 8766 PCIe Driver\n");
2260
2261 sema_init(&add_remove_card_sem, 1);
2262
2263 /* Clear the flag in case user removes the card. */
2264 user_rmmod = 0;
2265
2266 ret = pci_register_driver(&mwifiex_pcie);
2267 if (ret)
2268 pr_err("Driver register failed!\n");
2269 else
2270 pr_debug("info: Driver registered successfully!\n");
2271
2272 return ret;
2273}
2274
2275/*
2276 * This function cleans up the PCIE driver.
2277 *
2278 * The following major steps are followed for cleanup -
2279 * - Resume the device if its suspended
2280 * - Disconnect the device if connected
2281 * - Shutdown the firmware
2282 * - Unregister the device from PCIE bus.
2283 */
2284static void mwifiex_pcie_cleanup_module(void)
2285{
2286 if (!down_interruptible(&add_remove_card_sem))
2287 up(&add_remove_card_sem);
2288
2289 /* Set the flag as user is removing this module. */
2290 user_rmmod = 1;
2291
2292 pci_unregister_driver(&mwifiex_pcie);
2293}
2294
2295module_init(mwifiex_pcie_init_module);
2296module_exit(mwifiex_pcie_cleanup_module);
2297
2298MODULE_AUTHOR("Marvell International Ltd.");
2299MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2300MODULE_VERSION(PCIE_VERSION);
2301MODULE_LICENSE("GPL v2");
2302MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin");