blob: f7e8c73f1bc6bc2df2535e59742f8cca6ee33655 [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;
Amitkumar Karward930fae2011-10-11 17:41:21 -070039
Avinash Patilfc331462013-01-03 21:21:30 -080040static int
41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
42 int size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070043{
Avinash Patilfc331462013-01-03 21:21:30 -080044 struct pcie_service_card *card = adapter->card;
45 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -070046
Avinash Patilfc331462013-01-03 21:21:30 -080047 buf_pa = pci_map_single(card->dev, skb->data, size, flags);
48 if (pci_dma_mapping_error(card->dev, buf_pa)) {
49 dev_err(adapter->dev, "failed to map pci memory!\n");
50 return -1;
51 }
52 memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t));
53 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070054}
55
56/*
57 * This function reads sleep cookie and checks if FW is ready
58 */
59static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
60{
61 u32 *cookie_addr;
62 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080063 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
64
65 if (!reg->sleep_cookie)
66 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070067
Avinash Patilfc331462013-01-03 21:21:30 -080068 if (card->sleep_cookie_vbase) {
69 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070070 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
71 *cookie_addr);
72 if (*cookie_addr == FW_AWAKE_COOKIE)
73 return true;
74 }
75
76 return false;
77}
78
79/*
Bing Zhaofcca8d52013-03-04 16:27:53 -080080 * Kernel needs to suspend all functions separately. Therefore all
81 * registered functions must have drivers with suspend and resume
82 * methods. Failing that the kernel simply removes the whole card.
83 *
84 * If already not suspended, this function allocates and sends a host
85 * sleep activate request to the firmware and turns off the traffic.
86 */
87static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
88{
89 struct mwifiex_adapter *adapter;
90 struct pcie_service_card *card;
91 int hs_actived;
92
93 if (pdev) {
94 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
95 if (!card || !card->adapter) {
96 pr_err("Card or adapter structure is not valid\n");
97 return 0;
98 }
99 } else {
100 pr_err("PCIE device is not specified\n");
101 return 0;
102 }
103
104 adapter = card->adapter;
105
106 hs_actived = mwifiex_enable_hs(adapter);
107
108 /* Indicate device suspended */
109 adapter->is_suspended = true;
110
111 return 0;
112}
113
114/*
115 * Kernel needs to suspend all functions separately. Therefore all
116 * registered functions must have drivers with suspend and resume
117 * methods. Failing that the kernel simply removes the whole card.
118 *
119 * If already not resumed, this function turns on the traffic and
120 * sends a host sleep cancel request to the firmware.
121 */
122static int mwifiex_pcie_resume(struct pci_dev *pdev)
123{
124 struct mwifiex_adapter *adapter;
125 struct pcie_service_card *card;
126
127 if (pdev) {
128 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
129 if (!card || !card->adapter) {
130 pr_err("Card or adapter structure is not valid\n");
131 return 0;
132 }
133 } else {
134 pr_err("PCIE device is not specified\n");
135 return 0;
136 }
137
138 adapter = card->adapter;
139
140 if (!adapter->is_suspended) {
141 dev_warn(adapter->dev, "Device already resumed\n");
142 return 0;
143 }
144
145 adapter->is_suspended = false;
146
147 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
148 MWIFIEX_ASYNC_CMD);
149
150 return 0;
151}
152
153/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700154 * This function probes an mwifiex device and registers it. It allocates
155 * the card structure, enables PCIE function number and initiates the
156 * device registration and initialization procedure by adding a logical
157 * interface.
158 */
159static int mwifiex_pcie_probe(struct pci_dev *pdev,
160 const struct pci_device_id *ent)
161{
162 struct pcie_service_card *card;
163
164 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700165 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700166
167 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000168 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700169 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700170
171 card->dev = pdev;
172
Avinash Patildd04e6a2013-02-08 18:18:06 -0800173 if (ent->driver_data) {
174 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
175 card->pcie.firmware = data->firmware;
176 card->pcie.reg = data->reg;
177 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
178 }
179
Amitkumar Karward930fae2011-10-11 17:41:21 -0700180 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
181 MWIFIEX_PCIE)) {
182 pr_err("%s failed\n", __func__);
183 kfree(card);
184 return -1;
185 }
186
187 return 0;
188}
189
190/*
191 * This function removes the interface and frees up the card structure.
192 */
193static void mwifiex_pcie_remove(struct pci_dev *pdev)
194{
195 struct pcie_service_card *card;
196 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700197 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700198 int i;
199
200 card = pci_get_drvdata(pdev);
201 if (!card)
202 return;
203
204 adapter = card->adapter;
205 if (!adapter || !adapter->priv_num)
206 return;
207
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700208 /* In case driver is removed when asynchronous FW load is in progress */
209 wait_for_completion(&adapter->fw_load);
210
Amitkumar Karward930fae2011-10-11 17:41:21 -0700211 if (user_rmmod) {
212#ifdef CONFIG_PM
213 if (adapter->is_suspended)
214 mwifiex_pcie_resume(pdev);
215#endif
216
217 for (i = 0; i < adapter->priv_num; i++)
218 if ((GET_BSS_ROLE(adapter->priv[i]) ==
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700219 MWIFIEX_BSS_ROLE_STA) &&
220 adapter->priv[i]->media_connected)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700221 mwifiex_deauthenticate(adapter->priv[i], NULL);
222
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700223 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700224
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700225 mwifiex_disable_auto_ds(priv);
226
227 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700228 }
229
230 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
231 kfree(card);
232}
233
Amitkumar Karward930fae2011-10-11 17:41:21 -0700234static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
235 {
236 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
237 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800238 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700239 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800240 {
241 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
242 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
243 .driver_data = (unsigned long) &mwifiex_pcie8897,
244 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700245 {},
246};
247
248MODULE_DEVICE_TABLE(pci, mwifiex_ids);
249
250/* PCI Device Driver */
251static struct pci_driver __refdata mwifiex_pcie = {
252 .name = "mwifiex_pcie",
253 .id_table = mwifiex_ids,
254 .probe = mwifiex_pcie_probe,
255 .remove = mwifiex_pcie_remove,
256#ifdef CONFIG_PM
257 /* Power Management Hooks */
258 .suspend = mwifiex_pcie_suspend,
259 .resume = mwifiex_pcie_resume,
260#endif
261};
262
263/*
264 * This function writes data into PCIE card register.
265 */
266static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
267{
268 struct pcie_service_card *card = adapter->card;
269
270 iowrite32(data, card->pci_mmap1 + reg);
271
272 return 0;
273}
274
275/*
276 * This function reads data from PCIE card register.
277 */
278static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
279{
280 struct pcie_service_card *card = adapter->card;
281
282 *data = ioread32(card->pci_mmap1 + reg);
283
284 return 0;
285}
286
287/*
288 * This function wakes up the card.
289 *
290 * A host power up command is written to the card configuration
291 * register to wake up the card.
292 */
293static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
294{
295 int i = 0;
Avinash Patil52301a82013-02-12 14:38:32 -0800296 struct pcie_service_card *card = adapter->card;
297 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700298
Avinash Patil52301a82013-02-12 14:38:32 -0800299 while (reg->sleep_cookie && mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700300 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700301 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700302 /* 50ms max wait */
303 if (i == 50000)
304 break;
305 }
306
307 dev_dbg(adapter->dev, "event: Wakeup device...\n");
308
309 /* Enable interrupts or any chip access will wakeup device */
310 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) {
311 dev_warn(adapter->dev, "Enable host interrupt failed\n");
312 return -1;
313 }
314
315 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
316 adapter->ps_state = PS_STATE_AWAKE;
317
318 return 0;
319}
320
321/*
322 * This function is called after the card has woken up.
323 *
324 * The card configuration register is reset.
325 */
326static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
327{
328 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
329
330 return 0;
331}
332
333/*
334 * This function disables the host interrupt.
335 *
336 * The host interrupt mask is read, the disable bit is reset and
337 * written back to the card host interrupt mask register.
338 */
339static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
340{
341 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
342 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
343 0x00000000)) {
344 dev_warn(adapter->dev, "Disable host interrupt failed\n");
345 return -1;
346 }
347 }
348
349 return 0;
350}
351
352/*
353 * This function enables the host interrupt.
354 *
355 * The host interrupt enable mask is written to the card
356 * host interrupt mask register.
357 */
358static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
359{
360 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
361 /* Simply write the mask to the register */
362 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
363 HOST_INTR_MASK)) {
364 dev_warn(adapter->dev, "Enable host interrupt failed\n");
365 return -1;
366 }
367 }
368
369 return 0;
370}
371
372/*
Avinash Patil07324842013-02-08 18:18:07 -0800373 * This function initializes TX buffer ring descriptors
374 */
375static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
376{
377 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800378 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800379 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800380 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800381 int i;
382
383 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
384 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800385 if (reg->pfu_enabled) {
386 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
387 (sizeof(*desc2) * i);
388 desc2 = card->txbd_ring[i];
389 memset(desc2, 0, sizeof(*desc2));
390 } else {
391 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
392 (sizeof(*desc) * i);
393 desc = card->txbd_ring[i];
394 memset(desc, 0, sizeof(*desc));
395 }
Avinash Patil07324842013-02-08 18:18:07 -0800396 }
397
398 return 0;
399}
400
401/* This function initializes RX buffer ring descriptors. Each SKB is allocated
402 * here and after mapping PCI memory, its physical address is assigned to
403 * PCIE Rx buffer descriptor's physical address.
404 */
405static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
406{
407 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800408 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800409 struct sk_buff *skb;
410 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800411 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800412 dma_addr_t buf_pa;
413 int i;
414
415 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
416 /* Allocate skb here so that firmware can DMA data from it */
417 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
418 if (!skb) {
419 dev_err(adapter->dev,
420 "Unable to allocate skb for RX ring.\n");
421 kfree(card->rxbd_ring_vbase);
422 return -ENOMEM;
423 }
424
425 if (mwifiex_map_pci_memory(adapter, skb,
426 MWIFIEX_RX_DATA_BUF_SIZE,
427 PCI_DMA_FROMDEVICE))
428 return -1;
429
430 MWIFIEX_SKB_PACB(skb, &buf_pa);
431
432 dev_dbg(adapter->dev,
433 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
434 skb, skb->len, skb->data, (u32)buf_pa,
435 (u32)((u64)buf_pa >> 32));
436
437 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800438 if (reg->pfu_enabled) {
439 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
440 (sizeof(*desc2) * i);
441 desc2 = card->rxbd_ring[i];
442 desc2->paddr = buf_pa;
443 desc2->len = (u16)skb->len;
444 desc2->frag_len = (u16)skb->len;
445 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
446 desc2->offset = 0;
447 } else {
448 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
449 (sizeof(*desc) * i));
450 desc = card->rxbd_ring[i];
451 desc->paddr = buf_pa;
452 desc->len = (u16)skb->len;
453 desc->flags = 0;
454 }
Avinash Patil07324842013-02-08 18:18:07 -0800455 }
456
457 return 0;
458}
459
460/* This function initializes event buffer ring descriptors. Each SKB is
461 * allocated here and after mapping PCI memory, its physical address is assigned
462 * to PCIE Rx buffer descriptor's physical address
463 */
464static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
465{
466 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800467 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800468 struct sk_buff *skb;
469 dma_addr_t buf_pa;
470 int i;
471
472 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
473 /* Allocate skb here so that firmware can DMA data from it */
474 skb = dev_alloc_skb(MAX_EVENT_SIZE);
475 if (!skb) {
476 dev_err(adapter->dev,
477 "Unable to allocate skb for EVENT buf.\n");
478 kfree(card->evtbd_ring_vbase);
479 return -ENOMEM;
480 }
481 skb_put(skb, MAX_EVENT_SIZE);
482
483 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
484 PCI_DMA_FROMDEVICE))
485 return -1;
486
487 MWIFIEX_SKB_PACB(skb, &buf_pa);
488
489 dev_dbg(adapter->dev,
490 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
491 skb, skb->len, skb->data, (u32)buf_pa,
492 (u32)((u64)buf_pa >> 32));
493
494 card->evt_buf_list[i] = skb;
495 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
496 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800497 desc = card->evtbd_ring[i];
498 desc->paddr = buf_pa;
499 desc->len = (u16)skb->len;
500 desc->flags = 0;
501 }
502
503 return 0;
504}
505
506/* This function cleans up TX buffer rings. If any of the buffer list has valid
507 * SKB address, associated SKB is freed.
508 */
509static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
510{
511 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800512 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800513 struct sk_buff *skb;
514 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800515 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800516 int i;
517
518 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800519 if (reg->pfu_enabled) {
520 desc2 = card->txbd_ring[i];
521 if (card->tx_buf_list[i]) {
522 skb = card->tx_buf_list[i];
523 pci_unmap_single(card->dev, desc2->paddr,
524 skb->len, PCI_DMA_TODEVICE);
525 dev_kfree_skb_any(skb);
526 }
527 memset(desc2, 0, sizeof(*desc2));
528 } else {
529 desc = card->txbd_ring[i];
530 if (card->tx_buf_list[i]) {
531 skb = card->tx_buf_list[i];
532 pci_unmap_single(card->dev, desc->paddr,
533 skb->len, PCI_DMA_TODEVICE);
534 dev_kfree_skb_any(skb);
535 }
536 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800537 }
538 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800539 }
540
541 return;
542}
543
544/* This function cleans up RX buffer rings. If any of the buffer list has valid
545 * SKB address, associated SKB is freed.
546 */
547static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
548{
549 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800550 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800551 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800552 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800553 struct sk_buff *skb;
554 int i;
555
556 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800557 if (reg->pfu_enabled) {
558 desc2 = card->rxbd_ring[i];
559 if (card->rx_buf_list[i]) {
560 skb = card->rx_buf_list[i];
561 pci_unmap_single(card->dev, desc2->paddr,
562 skb->len, PCI_DMA_TODEVICE);
563 dev_kfree_skb_any(skb);
564 }
565 memset(desc2, 0, sizeof(*desc2));
566 } else {
567 desc = card->rxbd_ring[i];
568 if (card->rx_buf_list[i]) {
569 skb = card->rx_buf_list[i];
570 pci_unmap_single(card->dev, desc->paddr,
571 skb->len, PCI_DMA_TODEVICE);
572 dev_kfree_skb_any(skb);
573 }
574 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800575 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800576 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800577 }
578
579 return;
580}
581
582/* This function cleans up event buffer rings. If any of the buffer list has
583 * valid SKB address, associated SKB is freed.
584 */
585static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
586{
587 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800588 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800589 struct sk_buff *skb;
590 int i;
591
592 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
593 desc = card->evtbd_ring[i];
594 if (card->evt_buf_list[i]) {
595 skb = card->evt_buf_list[i];
596 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE,
597 PCI_DMA_FROMDEVICE);
598 dev_kfree_skb_any(skb);
599 }
600 card->evt_buf_list[i] = NULL;
601 memset(desc, 0, sizeof(*desc));
602 }
603
604 return;
605}
606
607/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700608 */
609static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
610{
611 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800612 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700613
614 /*
615 * driver maintaines the write pointer and firmware maintaines the read
616 * pointer. The write pointer starts at 0 (zero) while the read pointer
617 * starts at zero with rollover bit set
618 */
619 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800620
621 if (reg->pfu_enabled)
622 card->txbd_rdptr = 0;
623 else
624 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700625
626 /* allocate shared memory for the BD ring and divide the same in to
627 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800628 if (reg->pfu_enabled)
629 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
630 MWIFIEX_MAX_TXRX_BD;
631 else
632 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
633 MWIFIEX_MAX_TXRX_BD;
634
Amitkumar Karward930fae2011-10-11 17:41:21 -0700635 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700636 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800637 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
638 card->txbd_ring_size,
639 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700640 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800641 dev_err(adapter->dev,
642 "allocate consistent memory (%d bytes) failed!\n",
643 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800644 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700645 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700646 dev_dbg(adapter->dev,
647 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800648 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700649 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700650
Avinash Patil07324842013-02-08 18:18:07 -0800651 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700652}
653
654static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
655{
656 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800657 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700658
Avinash Patil07324842013-02-08 18:18:07 -0800659 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700660
Avinash Patilfc331462013-01-03 21:21:30 -0800661 if (card->txbd_ring_vbase)
662 pci_free_consistent(card->dev, card->txbd_ring_size,
663 card->txbd_ring_vbase,
664 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700665 card->txbd_ring_size = 0;
666 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800667 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700668 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800669 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700670
671 return 0;
672}
673
674/*
675 * This function creates buffer descriptor ring for RX
676 */
677static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
678{
679 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800680 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700681
682 /*
683 * driver maintaines the read pointer and firmware maintaines the write
684 * pointer. The write pointer starts at 0 (zero) while the read pointer
685 * starts at zero with rollover bit set
686 */
687 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800688 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700689
Avinash Patilca8f2112013-02-08 18:18:09 -0800690 if (reg->pfu_enabled)
691 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
692 MWIFIEX_MAX_TXRX_BD;
693 else
694 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
695 MWIFIEX_MAX_TXRX_BD;
696
Amitkumar Karward930fae2011-10-11 17:41:21 -0700697 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700698 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800699 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
700 card->rxbd_ring_size,
701 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700702 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800703 dev_err(adapter->dev,
704 "allocate consistent memory (%d bytes) failed!\n",
705 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800706 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700707 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700708
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700709 dev_dbg(adapter->dev,
710 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
711 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
712 (u32)((u64)card->rxbd_ring_pbase >> 32),
713 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700714
Avinash Patil07324842013-02-08 18:18:07 -0800715 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700716}
717
718/*
719 * This function deletes Buffer descriptor ring for RX
720 */
721static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
722{
723 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800724 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700725
Avinash Patil07324842013-02-08 18:18:07 -0800726 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700727
Avinash Patilfc331462013-01-03 21:21:30 -0800728 if (card->rxbd_ring_vbase)
729 pci_free_consistent(card->dev, card->rxbd_ring_size,
730 card->rxbd_ring_vbase,
731 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700732 card->rxbd_ring_size = 0;
733 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800734 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700735 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800736 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700737
738 return 0;
739}
740
741/*
742 * This function creates buffer descriptor ring for Events
743 */
744static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
745{
746 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800747 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700748
749 /*
750 * driver maintaines the read pointer and firmware maintaines the write
751 * pointer. The write pointer starts at 0 (zero) while the read pointer
752 * starts at zero with rollover bit set
753 */
754 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800755 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700756
Avinash Patile05dc3e2013-02-08 18:18:08 -0800757 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800758 MWIFIEX_MAX_EVT_BD;
759
Amitkumar Karward930fae2011-10-11 17:41:21 -0700760 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700761 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800762 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
763 card->evtbd_ring_size,
764 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700765 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700766 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800767 "allocate consistent memory (%d bytes) failed!\n",
768 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800769 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700770 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700771
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700772 dev_dbg(adapter->dev,
773 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
774 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
775 (u32)((u64)card->evtbd_ring_pbase >> 32),
776 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700777
Avinash Patil07324842013-02-08 18:18:07 -0800778 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700779}
780
781/*
782 * This function deletes Buffer descriptor ring for Events
783 */
784static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
785{
786 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800787 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700788
Avinash Patil07324842013-02-08 18:18:07 -0800789 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700790
Avinash Patilfc331462013-01-03 21:21:30 -0800791 if (card->evtbd_ring_vbase)
792 pci_free_consistent(card->dev, card->evtbd_ring_size,
793 card->evtbd_ring_vbase,
794 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700795 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800796 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700797 card->evtbd_ring_size = 0;
798 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800799 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700800
801 return 0;
802}
803
804/*
805 * This function allocates a buffer for CMDRSP
806 */
807static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
808{
809 struct pcie_service_card *card = adapter->card;
810 struct sk_buff *skb;
811
812 /* Allocate memory for receiving command response data */
813 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
814 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700815 dev_err(adapter->dev,
816 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700817 return -ENOMEM;
818 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700819 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800820 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
821 PCI_DMA_FROMDEVICE))
822 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700823
Avinash Patilfc331462013-01-03 21:21:30 -0800824 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700825
826 return 0;
827}
828
829/*
830 * This function deletes a buffer for CMDRSP
831 */
832static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
833{
834 struct pcie_service_card *card;
Avinash Patilfc331462013-01-03 21:21:30 -0800835 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700836
837 if (!adapter)
838 return 0;
839
840 card = adapter->card;
841
Avinash Patilfc331462013-01-03 21:21:30 -0800842 if (card && card->cmdrsp_buf) {
843 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
844 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
845 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700846 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800847 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700848
Avinash Patilfc331462013-01-03 21:21:30 -0800849 if (card && card->cmd_buf) {
850 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
851 pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER,
852 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700853 dev_kfree_skb_any(card->cmd_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800854 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700855 return 0;
856}
857
858/*
859 * This function allocates a buffer for sleep cookie
860 */
861static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
862{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700863 struct pcie_service_card *card = adapter->card;
864
Avinash Patilfc331462013-01-03 21:21:30 -0800865 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
866 &card->sleep_cookie_pbase);
867 if (!card->sleep_cookie_vbase) {
868 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700869 return -ENOMEM;
870 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700871 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800872 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700873
874 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800875 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700876
877 return 0;
878}
879
880/*
881 * This function deletes buffer for sleep cookie
882 */
883static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
884{
885 struct pcie_service_card *card;
886
887 if (!adapter)
888 return 0;
889
890 card = adapter->card;
891
Avinash Patilfc331462013-01-03 21:21:30 -0800892 if (card && card->sleep_cookie_vbase) {
893 pci_free_consistent(card->dev, sizeof(u32),
894 card->sleep_cookie_vbase,
895 card->sleep_cookie_pbase);
896 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700897 }
898
899 return 0;
900}
901
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800902/* This function flushes the TX buffer descriptor ring
903 * This function defined as handler is also called while cleaning TXRX
904 * during disconnect/ bss stop.
905 */
906static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
907{
908 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800909
Avinash Patil48f4d912013-02-20 21:12:58 -0800910 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800911 card->txbd_flush = 1;
912 /* write pointer already set at last send
913 * send dnld-rdy intr again, wait for completion.
914 */
915 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
916 CPU_INTR_DNLD_RDY)) {
917 dev_err(adapter->dev,
918 "failed to assert dnld-rdy interrupt.\n");
919 return -1;
920 }
921 }
922 return 0;
923}
924
Amitkumar Karward930fae2011-10-11 17:41:21 -0700925/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800926 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700927 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800928static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700929{
Avinash Patile7f767a2013-01-03 21:21:32 -0800930 struct sk_buff *skb;
931 dma_addr_t buf_pa;
Avinash Patilca8f2112013-02-08 18:18:09 -0800932 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800933 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800934 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700935 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800936 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700937
938 if (!mwifiex_pcie_ok_to_access_hw(adapter))
939 mwifiex_pm_wakeup_card(adapter);
940
941 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800942 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700943 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800944 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700945 return -1;
946 }
947
Avinash Patile7f767a2013-01-03 21:21:32 -0800948 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
949 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700950
Avinash Patilca8f2112013-02-08 18:18:09 -0800951 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800952 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800953 while (((card->txbd_rdptr & reg->tx_mask) !=
954 (rdptr & reg->tx_mask)) ||
955 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
956 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800957 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
958 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800959
960 skb = card->tx_buf_list[wrdoneidx];
961 if (skb) {
962 dev_dbg(adapter->dev,
963 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
964 skb, wrdoneidx);
965 MWIFIEX_SKB_PACB(skb, &buf_pa);
966 pci_unmap_single(card->dev, buf_pa, skb->len,
967 PCI_DMA_TODEVICE);
968
969 unmap_count++;
970
971 if (card->txbd_flush)
972 mwifiex_write_data_complete(adapter, skb, 0,
973 -1);
974 else
975 mwifiex_write_data_complete(adapter, skb, 0, 0);
976 }
977
978 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800979
980 if (reg->pfu_enabled) {
981 desc2 = (void *)card->txbd_ring[wrdoneidx];
982 memset(desc2, 0, sizeof(*desc2));
983 } else {
984 desc = card->txbd_ring[wrdoneidx];
985 memset(desc, 0, sizeof(*desc));
986 }
987 switch (card->dev->device) {
988 case PCIE_DEVICE_ID_MARVELL_88W8766P:
989 card->txbd_rdptr++;
990 break;
991 case PCIE_DEVICE_ID_MARVELL_88W8897:
992 card->txbd_rdptr += reg->ring_tx_start_ptr;
993 break;
994 }
995
Avinash Patile7f767a2013-01-03 21:21:32 -0800996
Avinash Patildd04e6a2013-02-08 18:18:06 -0800997 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -0800998 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -0800999 reg->tx_rollover_ind) ^
1000 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001001 }
1002
1003 if (unmap_count)
1004 adapter->data_sent = false;
1005
1006 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001007 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001008 card->txbd_flush = 0;
1009 else
1010 mwifiex_clean_pcie_ring_buf(adapter);
1011 }
1012
1013 return 0;
1014}
1015
1016/* This function sends data buffer to device. First 4 bytes of payload
1017 * are filled with payload length and payload type. Then this payload
1018 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1019 * Download ready interrupt to FW is deffered if Tx ring is not full and
1020 * additional payload can be accomodated.
1021 */
1022static int
1023mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1024 struct mwifiex_tx_param *tx_param)
1025{
1026 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001027 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001028 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001029 int ret;
1030 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001031 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001032 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patile7f767a2013-01-03 21:21:32 -08001033 __le16 *tmp;
1034
1035 if (!(skb->data && skb->len)) {
1036 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1037 __func__, skb->data, skb->len);
1038 return -1;
1039 }
1040
1041 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1042 mwifiex_pm_wakeup_card(adapter);
1043
Avinash Patilca8f2112013-02-08 18:18:09 -08001044 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001045 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1046 card->txbd_rdptr, card->txbd_wrptr);
1047 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001048 u8 *payload;
1049
1050 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001051 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001052 tmp = (__le16 *)&payload[0];
1053 *tmp = cpu_to_le16((u16)skb->len);
1054 tmp = (__le16 *)&payload[2];
1055 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001056
1057 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
1058 PCI_DMA_TODEVICE))
1059 return -1;
1060
Avinash Patilca8f2112013-02-08 18:18:09 -08001061 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001062 MWIFIEX_SKB_PACB(skb, &buf_pa);
1063 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001064
Avinash Patilca8f2112013-02-08 18:18:09 -08001065 if (reg->pfu_enabled) {
1066 desc2 = (void *)card->txbd_ring[wrindx];
1067 desc2->paddr = buf_pa;
1068 desc2->len = (u16)skb->len;
1069 desc2->frag_len = (u16)skb->len;
1070 desc2->offset = 0;
1071 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1072 MWIFIEX_BD_FLAG_LAST_DESC;
1073 } else {
1074 desc = card->txbd_ring[wrindx];
1075 desc->paddr = buf_pa;
1076 desc->len = (u16)skb->len;
1077 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1078 MWIFIEX_BD_FLAG_LAST_DESC;
1079 }
1080
1081 switch (card->dev->device) {
1082 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1083 card->txbd_wrptr++;
1084 break;
1085 case PCIE_DEVICE_ID_MARVELL_88W8897:
1086 card->txbd_wrptr += reg->ring_tx_start_ptr;
1087 break;
1088 }
1089
1090 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001091 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001092 reg->tx_rollover_ind) ^
1093 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001094
Avinash Patilca8f2112013-02-08 18:18:09 -08001095 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001096 /* Write the TX ring write pointer in to reg->tx_wrptr */
1097 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001098 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001099 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001100 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001101 ret = -1;
1102 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001103 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001104 if ((mwifiex_pcie_txbd_not_full(card)) &&
1105 tx_param->next_pkt_len) {
1106 /* have more packets and TxBD still can hold more */
1107 dev_dbg(adapter->dev,
1108 "SEND DATA: delay dnld-rdy interrupt.\n");
1109 adapter->data_sent = false;
1110 } else {
1111 /* Send the TX ready interrupt */
1112 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1113 CPU_INTR_DNLD_RDY)) {
1114 dev_err(adapter->dev,
1115 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1116 ret = -1;
1117 goto done_unmap;
1118 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001119 }
1120 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001121 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001122 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001123 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001124 dev_dbg(adapter->dev,
1125 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001126 adapter->data_sent = true;
1127 /* Send the TX ready interrupt */
1128 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1129 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001130 dev_err(adapter->dev,
1131 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001132 return -EBUSY;
1133 }
1134
Avinash Patile7f767a2013-01-03 21:21:32 -08001135 return -EINPROGRESS;
1136done_unmap:
1137 MWIFIEX_SKB_PACB(skb, &buf_pa);
1138 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1139 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001140 if (reg->pfu_enabled)
1141 memset(desc2, 0, sizeof(*desc2));
1142 else
1143 memset(desc, 0, sizeof(*desc));
1144
Avinash Patile7f767a2013-01-03 21:21:32 -08001145 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001146}
1147
1148/*
1149 * This function handles received buffer ring and
1150 * dispatches packets to upper
1151 */
1152static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1153{
1154 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001155 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001156 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001157 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001158 int ret = 0;
1159 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001160 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001161 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001162
Avinash Patile7f767a2013-01-03 21:21:32 -08001163 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1164 mwifiex_pm_wakeup_card(adapter);
1165
Amitkumar Karward930fae2011-10-11 17:41:21 -07001166 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001167 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001168 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001169 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001170 ret = -1;
1171 goto done;
1172 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001173 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001174
Avinash Patildd04e6a2013-02-08 18:18:06 -08001175 while (((wrptr & reg->rx_mask) !=
1176 (card->rxbd_rdptr & reg->rx_mask)) ||
1177 ((wrptr & reg->rx_rollover_ind) ==
1178 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001179 struct sk_buff *skb_data;
1180 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001181 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001182
Avinash Patildd04e6a2013-02-08 18:18:06 -08001183 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001184 skb_data = card->rx_buf_list[rd_index];
1185
Avinash Patile7f767a2013-01-03 21:21:32 -08001186 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1187 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1188 PCI_DMA_FROMDEVICE);
1189 card->rx_buf_list[rd_index] = NULL;
1190
Amitkumar Karward930fae2011-10-11 17:41:21 -07001191 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001192 * first 2 bytes for len, next 2 bytes is for type
1193 */
1194 pkt_len = *((__le16 *)skb_data->data);
1195 rx_len = le16_to_cpu(pkt_len);
1196 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001197 dev_dbg(adapter->dev,
1198 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1199 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001200 skb_pull(skb_data, INTF_HEADER_LEN);
1201 mwifiex_handle_rx_packet(adapter, skb_data);
1202
1203 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001204 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001205 dev_err(adapter->dev,
1206 "Unable to allocate skb.\n");
1207 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001208 }
1209
Avinash Patile7f767a2013-01-03 21:21:32 -08001210 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1211 MWIFIEX_RX_DATA_BUF_SIZE,
1212 PCI_DMA_FROMDEVICE))
1213 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001214
Avinash Patile7f767a2013-01-03 21:21:32 -08001215 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1216
1217 dev_dbg(adapter->dev,
1218 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1219 skb_tmp, rd_index);
1220 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001221
1222 if (reg->pfu_enabled) {
1223 desc2 = (void *)card->rxbd_ring[rd_index];
1224 desc2->paddr = buf_pa;
1225 desc2->len = skb_tmp->len;
1226 desc2->frag_len = skb_tmp->len;
1227 desc2->offset = 0;
1228 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1229 } else {
1230 desc = card->rxbd_ring[rd_index];
1231 desc->paddr = buf_pa;
1232 desc->len = skb_tmp->len;
1233 desc->flags = 0;
1234 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001235
Avinash Patildd04e6a2013-02-08 18:18:06 -08001236 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001237 MWIFIEX_MAX_TXRX_BD) {
1238 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001239 reg->rx_rollover_ind) ^
1240 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001241 }
1242 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001243 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001244
Avinash Patilca8f2112013-02-08 18:18:09 -08001245 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001246 /* Write the RX ring read pointer in to reg->rx_rdptr */
1247 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001248 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001249 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001250 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001251 ret = -1;
1252 goto done;
1253 }
1254
1255 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001256 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001257 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001258 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001259 ret = -1;
1260 goto done;
1261 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001262 dev_dbg(adapter->dev,
1263 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001264 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001265 }
1266
1267done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001268 return ret;
1269}
1270
1271/*
1272 * This function downloads the boot command to device
1273 */
1274static int
1275mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1276{
Avinash Patilfc331462013-01-03 21:21:30 -08001277 dma_addr_t buf_pa;
1278 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001279 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001280
Avinash Patilfc331462013-01-03 21:21:30 -08001281 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001282 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001283 "Invalid parameter in %s <%p. len %d>\n",
1284 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001285 return -1;
1286 }
1287
Avinash Patilfc331462013-01-03 21:21:30 -08001288 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1289 return -1;
1290
1291 MWIFIEX_SKB_PACB(skb, &buf_pa);
1292
Avinash Patildd04e6a2013-02-08 18:18:06 -08001293 /* Write the lower 32bits of the physical address to low command
1294 * address scratch register
1295 */
1296 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001297 dev_err(adapter->dev,
1298 "%s: failed to write download command to boot code.\n",
1299 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001300 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1301 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001302 return -1;
1303 }
1304
Avinash Patildd04e6a2013-02-08 18:18:06 -08001305 /* Write the upper 32bits of the physical address to high command
1306 * address scratch register
1307 */
1308 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001309 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001310 dev_err(adapter->dev,
1311 "%s: failed to write download command to boot code.\n",
1312 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001313 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1314 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001315 return -1;
1316 }
1317
Avinash Patildd04e6a2013-02-08 18:18:06 -08001318 /* Write the command length to cmd_size scratch register */
1319 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001320 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001321 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001322 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001323 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1324 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001325 return -1;
1326 }
1327
1328 /* Ring the door bell */
1329 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1330 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001331 dev_err(adapter->dev,
1332 "%s: failed to assert door-bell intr\n", __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001333 pci_unmap_single(card->dev, buf_pa,
1334 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001335 return -1;
1336 }
1337
1338 return 0;
1339}
1340
Avinash Patilc6d1d872013-01-03 21:21:29 -08001341/* This function init rx port in firmware which in turn enables to receive data
1342 * from device before transmitting any packet.
1343 */
1344static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1345{
1346 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001347 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001348 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001349
Avinash Patildd04e6a2013-02-08 18:18:06 -08001350 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001351 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1352 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001353 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001354 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001355 return -1;
1356 }
1357 return 0;
1358}
1359
1360/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001361 */
1362static int
1363mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1364{
1365 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001366 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001367 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001368 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1369 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001370
1371 if (!(skb->data && skb->len)) {
1372 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001373 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001374 return -1;
1375 }
1376
1377 /* Make sure a command response buffer is available */
1378 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001379 dev_err(adapter->dev,
1380 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001381 return -EBUSY;
1382 }
1383
Avinash Patilfc331462013-01-03 21:21:30 -08001384 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1385 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001386
1387 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001388
1389 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1390 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1391
1392 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1393 return -1;
1394
1395 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001396
1397 /* To send a command, the driver will:
1398 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001399 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001400 2. Ring the door bell (i.e. set the door bell interrupt)
1401
1402 In response to door bell interrupt, the firmware will perform
1403 the DMA of the command packet (first header to obtain the total
1404 length and then rest of the command).
1405 */
1406
1407 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001408 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001409 /* Write the lower 32bits of the cmdrsp buffer physical
1410 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001411 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001412 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001413 dev_err(adapter->dev,
1414 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001415 ret = -1;
1416 goto done;
1417 }
1418 /* Write the upper 32bits of the cmdrsp buffer physical
1419 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001420 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001421 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001422 dev_err(adapter->dev,
1423 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001424 ret = -1;
1425 goto done;
1426 }
1427 }
1428
Avinash Patilfc331462013-01-03 21:21:30 -08001429 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001430 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1431 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1432 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001433 dev_err(adapter->dev,
1434 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001435 ret = -1;
1436 goto done;
1437 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001438 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1439 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001440 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001441 dev_err(adapter->dev,
1442 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001443 ret = -1;
1444 goto done;
1445 }
1446
Avinash Patildd04e6a2013-02-08 18:18:06 -08001447 /* Write the command length to reg->cmd_size */
1448 if (mwifiex_write_reg(adapter, reg->cmd_size,
1449 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001450 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001451 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001452 ret = -1;
1453 goto done;
1454 }
1455
1456 /* Ring the door bell */
1457 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1458 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001459 dev_err(adapter->dev,
1460 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001461 ret = -1;
1462 goto done;
1463 }
1464
1465done:
1466 if (ret)
1467 adapter->cmd_sent = false;
1468
1469 return 0;
1470}
1471
1472/*
1473 * This function handles command complete interrupt
1474 */
1475static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1476{
1477 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001478 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001479 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001480 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001481 u16 rx_len;
1482 __le16 pkt_len;
1483 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001484
1485 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1486
Avinash Patilfc331462013-01-03 21:21:30 -08001487 MWIFIEX_SKB_PACB(skb, &buf_pa);
1488 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1489 PCI_DMA_FROMDEVICE);
1490
1491 pkt_len = *((__le16 *)skb->data);
1492 rx_len = le16_to_cpu(pkt_len);
1493 skb_trim(skb, rx_len);
1494 skb_pull(skb, INTF_HEADER_LEN);
1495
Amitkumar Karward930fae2011-10-11 17:41:21 -07001496 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001497 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001498 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1499 skb->len);
Avinash Patil52301a82013-02-12 14:38:32 -08001500 while (reg->sleep_cookie && (count++ < 10) &&
1501 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001502 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001503 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001504 dev_err(adapter->dev,
1505 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001506 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001507 memcpy(adapter->upld_buf, skb->data,
1508 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patilfc331462013-01-03 21:21:30 -08001509 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1510 PCI_DMA_FROMDEVICE))
1511 return -1;
1512
1513 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001514 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001515 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001516 adapter->cmd_resp_received = true;
1517 /* Take the pointer and set it to CMD node and will
1518 return in the response complete callback */
1519 card->cmdrsp_buf = NULL;
1520
1521 /* Clear the cmd-rsp buffer address in scratch registers. This
1522 will prevent firmware from writing to the same response
1523 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001524 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001525 dev_err(adapter->dev,
1526 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001527 return -1;
1528 }
1529 /* Write the upper 32bits of the cmdrsp buffer physical
1530 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001531 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001532 dev_err(adapter->dev,
1533 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001534 return -1;
1535 }
1536 }
1537
1538 return 0;
1539}
1540
1541/*
1542 * Command Response processing complete handler
1543 */
1544static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1545 struct sk_buff *skb)
1546{
1547 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001548 dma_addr_t buf_pa;
1549 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001550
1551 if (skb) {
1552 card->cmdrsp_buf = skb;
1553 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001554 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1555 PCI_DMA_FROMDEVICE))
1556 return -1;
1557 }
1558
1559 skb_tmp = card->cmd_buf;
1560 if (skb_tmp) {
1561 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1562 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1563 PCI_DMA_FROMDEVICE);
1564 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001565 }
1566
1567 return 0;
1568}
1569
1570/*
1571 * This function handles firmware event ready interrupt
1572 */
1573static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1574{
1575 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001576 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001577 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1578 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001579 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001580 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001581
1582 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1583 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001584
1585 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001586 dev_dbg(adapter->dev, "info: Event being processed, "
1587 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001588 return 0;
1589 }
1590
1591 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1592 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1593 return -1;
1594 }
1595
1596 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001597 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001598 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001599 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001600 return -1;
1601 }
1602
1603 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001604 card->evtbd_rdptr, wrptr);
1605 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1606 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001607 ((wrptr & reg->evt_rollover_ind) ==
1608 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001609 struct sk_buff *skb_cmd;
1610 __le16 data_len = 0;
1611 u16 evt_len;
1612
1613 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1614 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001615 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1616 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1617 PCI_DMA_FROMDEVICE);
1618
Amitkumar Karward930fae2011-10-11 17:41:21 -07001619 /* Take the pointer and set it to event pointer in adapter
1620 and will return back after event handling callback */
1621 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001622 desc = card->evtbd_ring[rdptr];
1623 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001624
1625 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1626 adapter->event_cause = event;
1627 /* The first 4bytes will be the event transfer header
1628 len is 2 bytes followed by type which is 2 bytes */
1629 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1630 evt_len = le16_to_cpu(data_len);
1631
1632 skb_pull(skb_cmd, INTF_HEADER_LEN);
1633 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1634
1635 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1636 memcpy(adapter->event_body, skb_cmd->data +
1637 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1638 MWIFIEX_EVENT_HEADER_LEN);
1639
1640 adapter->event_received = true;
1641 adapter->event_skb = skb_cmd;
1642
1643 /* Do not update the event read pointer here, wait till the
1644 buffer is released. This is just to make things simpler,
1645 we need to find a better method of managing these buffers.
1646 */
1647 }
1648
1649 return 0;
1650}
1651
1652/*
1653 * Event processing complete handler
1654 */
1655static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1656 struct sk_buff *skb)
1657{
1658 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001659 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001660 int ret = 0;
1661 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1662 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001663 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001664 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001665
1666 if (!skb)
1667 return 0;
1668
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001669 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001670 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001671 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001672 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001673 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001674
1675 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001676 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001677 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001678 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001679 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001680 }
1681
1682 if (!card->evt_buf_list[rdptr]) {
1683 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001684 if (mwifiex_map_pci_memory(adapter, skb,
1685 MAX_EVENT_SIZE,
1686 PCI_DMA_FROMDEVICE))
1687 return -1;
1688 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001689 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001690 MWIFIEX_SKB_PACB(skb, &buf_pa);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001691 desc = card->evtbd_ring[rdptr];
1692 desc->paddr = buf_pa;
1693 desc->len = (u16)skb->len;
1694 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001695 skb = NULL;
1696 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001697 dev_dbg(adapter->dev,
1698 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1699 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001700 }
1701
1702 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1703 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001704 reg->evt_rollover_ind) ^
1705 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001706 }
1707
1708 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001709 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001710
Avinash Patildd04e6a2013-02-08 18:18:06 -08001711 /* Write the event ring read pointer in to reg->evt_rdptr */
1712 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1713 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001714 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001715 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001716 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001717 }
1718
Amitkumar Karward930fae2011-10-11 17:41:21 -07001719 dev_dbg(adapter->dev, "info: Check Events Again\n");
1720 ret = mwifiex_pcie_process_event_ready(adapter);
1721
1722 return ret;
1723}
1724
1725/*
1726 * This function downloads the firmware to the card.
1727 *
1728 * Firmware is downloaded to the card in blocks. Every block download
1729 * is tested for CRC errors, and retried a number of times before
1730 * returning failure.
1731 */
1732static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1733 struct mwifiex_fw_image *fw)
1734{
1735 int ret;
1736 u8 *firmware = fw->fw_buf;
1737 u32 firmware_len = fw->fw_len;
1738 u32 offset = 0;
1739 struct sk_buff *skb;
1740 u32 txlen, tx_blocks = 0, tries, len;
1741 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001742 dma_addr_t buf_pa;
1743 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001744 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001745
1746 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001747 dev_err(adapter->dev,
1748 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001749 return -1;
1750 }
1751
1752 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001753 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001754
1755 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001756 dev_err(adapter->dev,
1757 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001758 return -1;
1759 }
1760
1761 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1762 if (!skb) {
1763 ret = -ENOMEM;
1764 goto done;
1765 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001766
1767 /* Perform firmware data transfer */
1768 do {
1769 u32 ireg_intr = 0;
1770
1771 /* More data? */
1772 if (offset >= firmware_len)
1773 break;
1774
1775 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001776 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001777 &len);
1778 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001779 dev_warn(adapter->dev,
1780 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001781 goto done;
1782 }
1783 if (len)
1784 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001785 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001786 }
1787
1788 if (!len) {
1789 break;
1790 } else if (len > MWIFIEX_UPLD_SIZE) {
1791 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001792 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001793 ret = -1;
1794 goto done;
1795 }
1796
1797 txlen = len;
1798
1799 if (len & BIT(0)) {
1800 block_retry_cnt++;
1801 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1802 pr_err("FW download failure @ %d, over max "
1803 "retry count\n", offset);
1804 ret = -1;
1805 goto done;
1806 }
1807 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001808 "helper: len = 0x%04X, txlen = %d\n",
1809 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001810 len &= ~BIT(0);
1811 /* Setting this to 0 to resend from same offset */
1812 txlen = 0;
1813 } else {
1814 block_retry_cnt = 0;
1815 /* Set blocksize to transfer - checking for
1816 last block */
1817 if (firmware_len - offset < txlen)
1818 txlen = firmware_len - offset;
1819
1820 dev_dbg(adapter->dev, ".");
1821
Avinash Patildd04e6a2013-02-08 18:18:06 -08001822 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1823 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001824
1825 /* Copy payload to buffer */
1826 memmove(skb->data, &firmware[offset], txlen);
1827 }
1828
1829 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001830 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001831
1832 /* Send the boot command to device */
1833 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001834 dev_err(adapter->dev,
1835 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001836 ret = -1;
1837 goto done;
1838 }
Avinash Patilfc331462013-01-03 21:21:30 -08001839
1840 MWIFIEX_SKB_PACB(skb, &buf_pa);
1841
Amitkumar Karward930fae2011-10-11 17:41:21 -07001842 /* Wait for the command done interrupt */
1843 do {
1844 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1845 &ireg_intr)) {
1846 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001847 "interrupt status during fw dnld.\n",
1848 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001849 pci_unmap_single(card->dev, buf_pa, skb->len,
1850 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001851 ret = -1;
1852 goto done;
1853 }
1854 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1855 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001856
1857 pci_unmap_single(card->dev, buf_pa, skb->len,
1858 PCI_DMA_TODEVICE);
1859
Amitkumar Karward930fae2011-10-11 17:41:21 -07001860 offset += txlen;
1861 } while (true);
1862
1863 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001864 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001865
1866 ret = 0;
1867
1868done:
1869 dev_kfree_skb_any(skb);
1870 return ret;
1871}
1872
1873/*
1874 * This function checks the firmware status in card.
1875 *
1876 * The winner interface is also determined by this function.
1877 */
1878static int
1879mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1880{
1881 int ret = 0;
1882 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001883 struct pcie_service_card *card = adapter->card;
1884 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001885 u32 tries;
1886
1887 /* Mask spurios interrupts */
1888 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001889 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001890 dev_warn(adapter->dev, "Write register failed\n");
1891 return -1;
1892 }
1893
1894 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001895 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1896 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001897 dev_err(adapter->dev,
1898 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001899 return -1;
1900 }
1901
1902 /* Wait for firmware initialization event */
1903 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001904 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001905 &firmware_stat))
1906 ret = -1;
1907 else
1908 ret = 0;
1909 if (ret)
1910 continue;
1911 if (firmware_stat == FIRMWARE_READY_PCIE) {
1912 ret = 0;
1913 break;
1914 } else {
1915 mdelay(100);
1916 ret = -1;
1917 }
1918 }
1919
1920 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001921 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001922 &winner_status))
1923 ret = -1;
1924 else if (!winner_status) {
1925 dev_err(adapter->dev, "PCI-E is the winner\n");
1926 adapter->winner = 1;
1927 ret = -1;
1928 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001929 dev_err(adapter->dev,
1930 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1931 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001932 ret = 0;
1933 }
1934 }
1935
1936 return ret;
1937}
1938
1939/*
1940 * This function reads the interrupt status from card.
1941 */
1942static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1943{
1944 u32 pcie_ireg;
1945 unsigned long flags;
1946
1947 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1948 return;
1949
1950 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1951 dev_warn(adapter->dev, "Read register failed\n");
1952 return;
1953 }
1954
1955 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1956
1957 mwifiex_pcie_disable_host_int(adapter);
1958
1959 /* Clear the pending interrupts */
1960 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1961 ~pcie_ireg)) {
1962 dev_warn(adapter->dev, "Write register failed\n");
1963 return;
1964 }
1965 spin_lock_irqsave(&adapter->int_lock, flags);
1966 adapter->int_status |= pcie_ireg;
1967 spin_unlock_irqrestore(&adapter->int_lock, flags);
1968
1969 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1970 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1971 (adapter->ps_state == PS_STATE_SLEEP)) {
1972 mwifiex_pcie_enable_host_int(adapter);
1973 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001974 PCIE_CPU_INT_EVENT,
1975 CPU_INTR_SLEEP_CFM_DONE)
1976 ) {
1977 dev_warn(adapter->dev,
1978 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001979 return;
1980
1981 }
1982 }
1983 } else if (!adapter->pps_uapsd_mode &&
1984 adapter->ps_state == PS_STATE_SLEEP) {
1985 /* Potentially for PCIe we could get other
1986 * interrupts like shared. Don't change power
1987 * state until cookie is set */
1988 if (mwifiex_pcie_ok_to_access_hw(adapter))
1989 adapter->ps_state = PS_STATE_AWAKE;
1990 }
1991 }
1992}
1993
1994/*
1995 * Interrupt handler for PCIe root port
1996 *
1997 * This function reads the interrupt status from firmware and assigns
1998 * the main process in workqueue which will handle the interrupt.
1999 */
2000static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2001{
2002 struct pci_dev *pdev = (struct pci_dev *)context;
2003 struct pcie_service_card *card;
2004 struct mwifiex_adapter *adapter;
2005
2006 if (!pdev) {
2007 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2008 goto exit;
2009 }
2010
2011 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
2012 if (!card || !card->adapter) {
2013 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002014 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002015 goto exit;
2016 }
2017 adapter = card->adapter;
2018
2019 if (adapter->surprise_removed)
2020 goto exit;
2021
2022 mwifiex_interrupt_status(adapter);
2023 queue_work(adapter->workqueue, &adapter->main_work);
2024
2025exit:
2026 return IRQ_HANDLED;
2027}
2028
2029/*
2030 * This function checks the current interrupt status.
2031 *
2032 * The following interrupts are checked and handled by this function -
2033 * - Data sent
2034 * - Command sent
2035 * - Command received
2036 * - Packets received
2037 * - Events received
2038 *
2039 * In case of Rx packets received, the packets are uploaded from card to
2040 * host and processed accordingly.
2041 */
2042static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2043{
2044 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002045 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002046 unsigned long flags;
2047
2048 spin_lock_irqsave(&adapter->int_lock, flags);
2049 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002050 pcie_ireg = adapter->int_status;
2051 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002052 spin_unlock_irqrestore(&adapter->int_lock, flags);
2053
Avinash Patil659c4782013-01-03 21:21:28 -08002054 while (pcie_ireg & HOST_INTR_MASK) {
2055 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2056 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002057 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2058 ret = mwifiex_pcie_send_data_complete(adapter);
2059 if (ret)
2060 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002061 }
Avinash Patil659c4782013-01-03 21:21:28 -08002062 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2063 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002064 dev_dbg(adapter->dev, "info: Rx DATA\n");
2065 ret = mwifiex_pcie_process_recv_data(adapter);
2066 if (ret)
2067 return ret;
2068 }
Avinash Patil659c4782013-01-03 21:21:28 -08002069 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2070 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002071 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2072 ret = mwifiex_pcie_process_event_ready(adapter);
2073 if (ret)
2074 return ret;
2075 }
2076
Avinash Patil659c4782013-01-03 21:21:28 -08002077 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2078 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002079 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002080 dev_dbg(adapter->dev,
2081 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002082 adapter->cmd_sent = false;
2083 }
2084 /* Handle command response */
2085 ret = mwifiex_pcie_process_cmd_complete(adapter);
2086 if (ret)
2087 return ret;
2088 }
2089
2090 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2091 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2092 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002093 dev_warn(adapter->dev,
2094 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002095 return -1;
2096 }
2097
2098 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2099 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002100 PCIE_HOST_INT_STATUS,
2101 ~pcie_ireg)) {
2102 dev_warn(adapter->dev,
2103 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002104 return -1;
2105 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002106 }
2107
2108 }
2109 }
2110 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002111 adapter->cmd_sent, adapter->data_sent);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002112 mwifiex_pcie_enable_host_int(adapter);
2113
2114 return 0;
2115}
2116
2117/*
2118 * This function downloads data from driver to card.
2119 *
2120 * Both commands and data packets are transferred to the card by this
2121 * function.
2122 *
2123 * This function adds the PCIE specific header to the front of the buffer
2124 * before transferring. The header contains the length of the packet and
2125 * the type. The firmware handles the packets based upon this set type.
2126 */
2127static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2128 struct sk_buff *skb,
2129 struct mwifiex_tx_param *tx_param)
2130{
Dan Carpenterfa161cb72011-11-07 19:31:45 -08002131 if (!skb) {
2132 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002133 return -1;
2134 }
2135
2136 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002137 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002138 else if (type == MWIFIEX_TYPE_CMD)
2139 return mwifiex_pcie_send_cmd(adapter, skb);
2140
2141 return 0;
2142}
2143
2144/*
2145 * This function initializes the PCI-E host memory space, WCB rings, etc.
2146 *
2147 * The following initializations steps are followed -
2148 * - Allocate TXBD ring buffers
2149 * - Allocate RXBD ring buffers
2150 * - Allocate event BD ring buffers
2151 * - Allocate command response ring buffer
2152 * - Allocate sleep cookie buffer
2153 */
2154static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2155{
2156 struct pcie_service_card *card = adapter->card;
2157 int ret;
2158 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002159 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002160
2161 pci_set_drvdata(pdev, card);
2162
2163 ret = pci_enable_device(pdev);
2164 if (ret)
2165 goto err_enable_dev;
2166
2167 pci_set_master(pdev);
2168
2169 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2170 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2171 if (ret) {
2172 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2173 goto err_set_dma_mask;
2174 }
2175
2176 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2177 if (ret) {
2178 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2179 goto err_set_dma_mask;
2180 }
2181
2182 ret = pci_request_region(pdev, 0, DRV_NAME);
2183 if (ret) {
2184 dev_err(adapter->dev, "req_reg(0) error\n");
2185 goto err_req_region0;
2186 }
2187 card->pci_mmap = pci_iomap(pdev, 0, 0);
2188 if (!card->pci_mmap) {
2189 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002190 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002191 goto err_iomap0;
2192 }
2193 ret = pci_request_region(pdev, 2, DRV_NAME);
2194 if (ret) {
2195 dev_err(adapter->dev, "req_reg(2) error\n");
2196 goto err_req_region2;
2197 }
2198 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2199 if (!card->pci_mmap1) {
2200 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002201 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002202 goto err_iomap2;
2203 }
2204
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002205 dev_dbg(adapter->dev,
2206 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2207 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002208
2209 card->cmdrsp_buf = NULL;
2210 ret = mwifiex_pcie_create_txbd_ring(adapter);
2211 if (ret)
2212 goto err_cre_txbd;
2213 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2214 if (ret)
2215 goto err_cre_rxbd;
2216 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2217 if (ret)
2218 goto err_cre_evtbd;
2219 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2220 if (ret)
2221 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002222 if (reg->sleep_cookie) {
2223 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2224 if (ret)
2225 goto err_alloc_cookie;
2226 } else {
2227 card->sleep_cookie_vbase = NULL;
2228 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002229 return ret;
2230
2231err_alloc_cookie:
2232 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2233err_alloc_cmdbuf:
2234 mwifiex_pcie_delete_evtbd_ring(adapter);
2235err_cre_evtbd:
2236 mwifiex_pcie_delete_rxbd_ring(adapter);
2237err_cre_rxbd:
2238 mwifiex_pcie_delete_txbd_ring(adapter);
2239err_cre_txbd:
2240 pci_iounmap(pdev, card->pci_mmap1);
2241err_iomap2:
2242 pci_release_region(pdev, 2);
2243err_req_region2:
2244 pci_iounmap(pdev, card->pci_mmap);
2245err_iomap0:
2246 pci_release_region(pdev, 0);
2247err_req_region0:
2248err_set_dma_mask:
2249 pci_disable_device(pdev);
2250err_enable_dev:
2251 pci_set_drvdata(pdev, NULL);
2252 return ret;
2253}
2254
2255/*
2256 * This function cleans up the allocated card buffers.
2257 *
2258 * The following are freed by this function -
2259 * - TXBD ring buffers
2260 * - RXBD ring buffers
2261 * - Event BD ring buffers
2262 * - Command response ring buffer
2263 * - Sleep cookie buffer
2264 */
2265static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2266{
2267 struct pcie_service_card *card = adapter->card;
2268 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002269 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002270
Amitkumar Karward930fae2011-10-11 17:41:21 -07002271 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002272 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002273 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002274 dev_err(adapter->dev,
2275 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002276 }
2277
2278 if (pdev) {
2279 pci_iounmap(pdev, card->pci_mmap);
2280 pci_iounmap(pdev, card->pci_mmap1);
2281
2282 pci_release_regions(pdev);
2283 pci_disable_device(pdev);
2284 pci_set_drvdata(pdev, NULL);
2285 }
2286}
2287
2288/*
2289 * This function registers the PCIE device.
2290 *
2291 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2292 */
2293static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2294{
2295 int ret;
2296 struct pcie_service_card *card = adapter->card;
2297 struct pci_dev *pdev = card->dev;
2298
2299 /* save adapter pointer in card */
2300 card->adapter = adapter;
2301
2302 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2303 "MRVL_PCIE", pdev);
2304 if (ret) {
2305 pr_err("request_irq failed: ret=%d\n", ret);
2306 adapter->card = NULL;
2307 return -1;
2308 }
2309
2310 adapter->dev = &pdev->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002311 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002312
2313 return 0;
2314}
2315
2316/*
2317 * This function unregisters the PCIE device.
2318 *
2319 * The PCIE IRQ is released, the function is disabled and driver
2320 * data is set to null.
2321 */
2322static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2323{
2324 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002325 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002326
2327 if (card) {
2328 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2329 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002330
Avinash Patil52301a82013-02-12 14:38:32 -08002331 reg = card->pcie.reg;
2332 if (reg->sleep_cookie)
2333 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2334
Avinash Patilfc331462013-01-03 21:21:30 -08002335 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2336 mwifiex_pcie_delete_evtbd_ring(adapter);
2337 mwifiex_pcie_delete_rxbd_ring(adapter);
2338 mwifiex_pcie_delete_txbd_ring(adapter);
2339 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002340 }
2341}
2342
2343static struct mwifiex_if_ops pcie_ops = {
2344 .init_if = mwifiex_pcie_init,
2345 .cleanup_if = mwifiex_pcie_cleanup,
2346 .check_fw_status = mwifiex_check_fw_status,
2347 .prog_fw = mwifiex_prog_fw_w_helper,
2348 .register_dev = mwifiex_register_dev,
2349 .unregister_dev = mwifiex_unregister_dev,
2350 .enable_int = mwifiex_pcie_enable_host_int,
2351 .process_int_status = mwifiex_process_int_status,
2352 .host_to_card = mwifiex_pcie_host_to_card,
2353 .wakeup = mwifiex_pm_wakeup_card,
2354 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2355
2356 /* PCIE specific */
2357 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2358 .event_complete = mwifiex_pcie_event_complete,
2359 .update_mp_end_port = NULL,
2360 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002361 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002362 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002363};
2364
2365/*
2366 * This function initializes the PCIE driver module.
2367 *
2368 * This initiates the semaphore and registers the device with
2369 * PCIE bus.
2370 */
2371static int mwifiex_pcie_init_module(void)
2372{
2373 int ret;
2374
Avinash Patilca8f2112013-02-08 18:18:09 -08002375 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002376
2377 sema_init(&add_remove_card_sem, 1);
2378
2379 /* Clear the flag in case user removes the card. */
2380 user_rmmod = 0;
2381
2382 ret = pci_register_driver(&mwifiex_pcie);
2383 if (ret)
2384 pr_err("Driver register failed!\n");
2385 else
2386 pr_debug("info: Driver registered successfully!\n");
2387
2388 return ret;
2389}
2390
2391/*
2392 * This function cleans up the PCIE driver.
2393 *
2394 * The following major steps are followed for cleanup -
2395 * - Resume the device if its suspended
2396 * - Disconnect the device if connected
2397 * - Shutdown the firmware
2398 * - Unregister the device from PCIE bus.
2399 */
2400static void mwifiex_pcie_cleanup_module(void)
2401{
2402 if (!down_interruptible(&add_remove_card_sem))
2403 up(&add_remove_card_sem);
2404
2405 /* Set the flag as user is removing this module. */
2406 user_rmmod = 1;
2407
2408 pci_unregister_driver(&mwifiex_pcie);
2409}
2410
2411module_init(mwifiex_pcie_init_module);
2412module_exit(mwifiex_pcie_cleanup_module);
2413
2414MODULE_AUTHOR("Marvell International Ltd.");
2415MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2416MODULE_VERSION(PCIE_VERSION);
2417MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002418MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2419MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);