blob: 1662b99dd14831930f58908bb22ef34ec42b2eb0 [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
Bing Zhao8509e822013-03-04 16:27:54 -080079#ifdef CONFIG_PM
Amitkumar Karward930fae2011-10-11 17:41:21 -070080/*
Bing Zhaofcca8d52013-03-04 16:27:53 -080081 * Kernel needs to suspend all functions separately. Therefore all
82 * registered functions must have drivers with suspend and resume
83 * methods. Failing that the kernel simply removes the whole card.
84 *
85 * If already not suspended, this function allocates and sends a host
86 * sleep activate request to the firmware and turns off the traffic.
87 */
88static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
89{
90 struct mwifiex_adapter *adapter;
91 struct pcie_service_card *card;
92 int hs_actived;
93
94 if (pdev) {
95 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
96 if (!card || !card->adapter) {
97 pr_err("Card or adapter structure is not valid\n");
98 return 0;
99 }
100 } else {
101 pr_err("PCIE device is not specified\n");
102 return 0;
103 }
104
105 adapter = card->adapter;
106
107 hs_actived = mwifiex_enable_hs(adapter);
108
109 /* Indicate device suspended */
110 adapter->is_suspended = true;
111
112 return 0;
113}
114
115/*
116 * Kernel needs to suspend all functions separately. Therefore all
117 * registered functions must have drivers with suspend and resume
118 * methods. Failing that the kernel simply removes the whole card.
119 *
120 * If already not resumed, this function turns on the traffic and
121 * sends a host sleep cancel request to the firmware.
122 */
123static int mwifiex_pcie_resume(struct pci_dev *pdev)
124{
125 struct mwifiex_adapter *adapter;
126 struct pcie_service_card *card;
127
128 if (pdev) {
129 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
130 if (!card || !card->adapter) {
131 pr_err("Card or adapter structure is not valid\n");
132 return 0;
133 }
134 } else {
135 pr_err("PCIE device is not specified\n");
136 return 0;
137 }
138
139 adapter = card->adapter;
140
141 if (!adapter->is_suspended) {
142 dev_warn(adapter->dev, "Device already resumed\n");
143 return 0;
144 }
145
146 adapter->is_suspended = false;
147
148 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
149 MWIFIEX_ASYNC_CMD);
150
151 return 0;
152}
Bing Zhao8509e822013-03-04 16:27:54 -0800153#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800154
155/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700156 * This function probes an mwifiex device and registers it. It allocates
157 * the card structure, enables PCIE function number and initiates the
158 * device registration and initialization procedure by adding a logical
159 * interface.
160 */
161static int mwifiex_pcie_probe(struct pci_dev *pdev,
162 const struct pci_device_id *ent)
163{
164 struct pcie_service_card *card;
165
166 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700167 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700168
169 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000170 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700171 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700172
173 card->dev = pdev;
174
Avinash Patildd04e6a2013-02-08 18:18:06 -0800175 if (ent->driver_data) {
176 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
177 card->pcie.firmware = data->firmware;
178 card->pcie.reg = data->reg;
179 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
180 }
181
Amitkumar Karward930fae2011-10-11 17:41:21 -0700182 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
183 MWIFIEX_PCIE)) {
184 pr_err("%s failed\n", __func__);
185 kfree(card);
186 return -1;
187 }
188
189 return 0;
190}
191
192/*
193 * This function removes the interface and frees up the card structure.
194 */
195static void mwifiex_pcie_remove(struct pci_dev *pdev)
196{
197 struct pcie_service_card *card;
198 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700199 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700200 int i;
201
202 card = pci_get_drvdata(pdev);
203 if (!card)
204 return;
205
206 adapter = card->adapter;
207 if (!adapter || !adapter->priv_num)
208 return;
209
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700210 /* In case driver is removed when asynchronous FW load is in progress */
211 wait_for_completion(&adapter->fw_load);
212
Amitkumar Karward930fae2011-10-11 17:41:21 -0700213 if (user_rmmod) {
214#ifdef CONFIG_PM
215 if (adapter->is_suspended)
216 mwifiex_pcie_resume(pdev);
217#endif
218
219 for (i = 0; i < adapter->priv_num; i++)
220 if ((GET_BSS_ROLE(adapter->priv[i]) ==
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700221 MWIFIEX_BSS_ROLE_STA) &&
222 adapter->priv[i]->media_connected)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700223 mwifiex_deauthenticate(adapter->priv[i], NULL);
224
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700225 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700226
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700227 mwifiex_disable_auto_ds(priv);
228
229 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700230 }
231
232 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
233 kfree(card);
234}
235
Amitkumar Karward930fae2011-10-11 17:41:21 -0700236static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
237 {
238 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
239 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800240 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700241 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800242 {
243 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
244 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
245 .driver_data = (unsigned long) &mwifiex_pcie8897,
246 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700247 {},
248};
249
250MODULE_DEVICE_TABLE(pci, mwifiex_ids);
251
252/* PCI Device Driver */
253static struct pci_driver __refdata mwifiex_pcie = {
254 .name = "mwifiex_pcie",
255 .id_table = mwifiex_ids,
256 .probe = mwifiex_pcie_probe,
257 .remove = mwifiex_pcie_remove,
258#ifdef CONFIG_PM
259 /* Power Management Hooks */
260 .suspend = mwifiex_pcie_suspend,
261 .resume = mwifiex_pcie_resume,
262#endif
263};
264
265/*
266 * This function writes data into PCIE card register.
267 */
268static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
269{
270 struct pcie_service_card *card = adapter->card;
271
272 iowrite32(data, card->pci_mmap1 + reg);
273
274 return 0;
275}
276
277/*
278 * This function reads data from PCIE card register.
279 */
280static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
281{
282 struct pcie_service_card *card = adapter->card;
283
284 *data = ioread32(card->pci_mmap1 + reg);
285
286 return 0;
287}
288
289/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700290 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700291 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700292static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700293{
294 int i = 0;
295
Avinash Patilc0880a22013-03-22 21:49:07 -0700296 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700297 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700298 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700299 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800300 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700301 break;
302 }
303
Avinash Patilc0880a22013-03-22 21:49:07 -0700304 return;
305}
306
307/* This function wakes up the card by reading fw_status register. */
308static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
309{
310 u32 fw_status;
311 struct pcie_service_card *card = adapter->card;
312 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
313
Amitkumar Karward930fae2011-10-11 17:41:21 -0700314 dev_dbg(adapter->dev, "event: Wakeup device...\n");
315
Avinash Patilc0880a22013-03-22 21:49:07 -0700316 if (reg->sleep_cookie)
317 mwifiex_pcie_dev_wakeup_delay(adapter);
318
319 /* Reading fw_status register will wakeup device */
320 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
321 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700322 return -1;
323 }
324
Avinash Patilc0880a22013-03-22 21:49:07 -0700325 if (reg->sleep_cookie) {
326 mwifiex_pcie_dev_wakeup_delay(adapter);
327 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
328 adapter->ps_state = PS_STATE_AWAKE;
329 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700330
331 return 0;
332}
333
334/*
335 * This function is called after the card has woken up.
336 *
337 * The card configuration register is reset.
338 */
339static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
340{
341 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
342
343 return 0;
344}
345
346/*
347 * This function disables the host interrupt.
348 *
349 * The host interrupt mask is read, the disable bit is reset and
350 * written back to the card host interrupt mask register.
351 */
352static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
353{
354 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
355 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
356 0x00000000)) {
357 dev_warn(adapter->dev, "Disable host interrupt failed\n");
358 return -1;
359 }
360 }
361
362 return 0;
363}
364
365/*
366 * This function enables the host interrupt.
367 *
368 * The host interrupt enable mask is written to the card
369 * host interrupt mask register.
370 */
371static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
372{
373 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
374 /* Simply write the mask to the register */
375 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
376 HOST_INTR_MASK)) {
377 dev_warn(adapter->dev, "Enable host interrupt failed\n");
378 return -1;
379 }
380 }
381
382 return 0;
383}
384
385/*
Avinash Patil07324842013-02-08 18:18:07 -0800386 * This function initializes TX buffer ring descriptors
387 */
388static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
389{
390 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800391 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800392 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800393 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800394 int i;
395
396 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
397 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800398 if (reg->pfu_enabled) {
399 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
400 (sizeof(*desc2) * i);
401 desc2 = card->txbd_ring[i];
402 memset(desc2, 0, sizeof(*desc2));
403 } else {
404 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
405 (sizeof(*desc) * i);
406 desc = card->txbd_ring[i];
407 memset(desc, 0, sizeof(*desc));
408 }
Avinash Patil07324842013-02-08 18:18:07 -0800409 }
410
411 return 0;
412}
413
414/* This function initializes RX buffer ring descriptors. Each SKB is allocated
415 * here and after mapping PCI memory, its physical address is assigned to
416 * PCIE Rx buffer descriptor's physical address.
417 */
418static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
419{
420 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800421 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800422 struct sk_buff *skb;
423 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800424 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800425 dma_addr_t buf_pa;
426 int i;
427
428 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
429 /* Allocate skb here so that firmware can DMA data from it */
430 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
431 if (!skb) {
432 dev_err(adapter->dev,
433 "Unable to allocate skb for RX ring.\n");
434 kfree(card->rxbd_ring_vbase);
435 return -ENOMEM;
436 }
437
438 if (mwifiex_map_pci_memory(adapter, skb,
439 MWIFIEX_RX_DATA_BUF_SIZE,
440 PCI_DMA_FROMDEVICE))
441 return -1;
442
443 MWIFIEX_SKB_PACB(skb, &buf_pa);
444
445 dev_dbg(adapter->dev,
446 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
447 skb, skb->len, skb->data, (u32)buf_pa,
448 (u32)((u64)buf_pa >> 32));
449
450 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800451 if (reg->pfu_enabled) {
452 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
453 (sizeof(*desc2) * i);
454 desc2 = card->rxbd_ring[i];
455 desc2->paddr = buf_pa;
456 desc2->len = (u16)skb->len;
457 desc2->frag_len = (u16)skb->len;
458 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
459 desc2->offset = 0;
460 } else {
461 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
462 (sizeof(*desc) * i));
463 desc = card->rxbd_ring[i];
464 desc->paddr = buf_pa;
465 desc->len = (u16)skb->len;
466 desc->flags = 0;
467 }
Avinash Patil07324842013-02-08 18:18:07 -0800468 }
469
470 return 0;
471}
472
473/* This function initializes event buffer ring descriptors. Each SKB is
474 * allocated here and after mapping PCI memory, its physical address is assigned
475 * to PCIE Rx buffer descriptor's physical address
476 */
477static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
478{
479 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800480 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800481 struct sk_buff *skb;
482 dma_addr_t buf_pa;
483 int i;
484
485 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
486 /* Allocate skb here so that firmware can DMA data from it */
487 skb = dev_alloc_skb(MAX_EVENT_SIZE);
488 if (!skb) {
489 dev_err(adapter->dev,
490 "Unable to allocate skb for EVENT buf.\n");
491 kfree(card->evtbd_ring_vbase);
492 return -ENOMEM;
493 }
494 skb_put(skb, MAX_EVENT_SIZE);
495
496 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
497 PCI_DMA_FROMDEVICE))
498 return -1;
499
500 MWIFIEX_SKB_PACB(skb, &buf_pa);
501
502 dev_dbg(adapter->dev,
503 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
504 skb, skb->len, skb->data, (u32)buf_pa,
505 (u32)((u64)buf_pa >> 32));
506
507 card->evt_buf_list[i] = skb;
508 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
509 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800510 desc = card->evtbd_ring[i];
511 desc->paddr = buf_pa;
512 desc->len = (u16)skb->len;
513 desc->flags = 0;
514 }
515
516 return 0;
517}
518
519/* This function cleans up TX buffer rings. If any of the buffer list has valid
520 * SKB address, associated SKB is freed.
521 */
522static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
523{
524 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800525 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800526 struct sk_buff *skb;
527 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800528 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800529 int i;
530
531 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800532 if (reg->pfu_enabled) {
533 desc2 = card->txbd_ring[i];
534 if (card->tx_buf_list[i]) {
535 skb = card->tx_buf_list[i];
536 pci_unmap_single(card->dev, desc2->paddr,
537 skb->len, PCI_DMA_TODEVICE);
538 dev_kfree_skb_any(skb);
539 }
540 memset(desc2, 0, sizeof(*desc2));
541 } else {
542 desc = card->txbd_ring[i];
543 if (card->tx_buf_list[i]) {
544 skb = card->tx_buf_list[i];
545 pci_unmap_single(card->dev, desc->paddr,
546 skb->len, PCI_DMA_TODEVICE);
547 dev_kfree_skb_any(skb);
548 }
549 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800550 }
551 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800552 }
553
554 return;
555}
556
557/* This function cleans up RX buffer rings. If any of the buffer list has valid
558 * SKB address, associated SKB is freed.
559 */
560static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
561{
562 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800563 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800564 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800565 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800566 struct sk_buff *skb;
567 int i;
568
569 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800570 if (reg->pfu_enabled) {
571 desc2 = card->rxbd_ring[i];
572 if (card->rx_buf_list[i]) {
573 skb = card->rx_buf_list[i];
574 pci_unmap_single(card->dev, desc2->paddr,
Avinash Patild033d3a2013-04-19 17:44:42 -0700575 skb->len, PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800576 dev_kfree_skb_any(skb);
577 }
578 memset(desc2, 0, sizeof(*desc2));
579 } else {
580 desc = card->rxbd_ring[i];
581 if (card->rx_buf_list[i]) {
582 skb = card->rx_buf_list[i];
583 pci_unmap_single(card->dev, desc->paddr,
Avinash Patild033d3a2013-04-19 17:44:42 -0700584 skb->len, PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800585 dev_kfree_skb_any(skb);
586 }
587 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800588 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800589 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800590 }
591
592 return;
593}
594
595/* This function cleans up event buffer rings. If any of the buffer list has
596 * valid SKB address, associated SKB is freed.
597 */
598static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
599{
600 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800601 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800602 struct sk_buff *skb;
603 int i;
604
605 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
606 desc = card->evtbd_ring[i];
607 if (card->evt_buf_list[i]) {
608 skb = card->evt_buf_list[i];
609 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE,
610 PCI_DMA_FROMDEVICE);
611 dev_kfree_skb_any(skb);
612 }
613 card->evt_buf_list[i] = NULL;
614 memset(desc, 0, sizeof(*desc));
615 }
616
617 return;
618}
619
620/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700621 */
622static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
623{
624 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800625 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700626
627 /*
628 * driver maintaines the write pointer and firmware maintaines the read
629 * pointer. The write pointer starts at 0 (zero) while the read pointer
630 * starts at zero with rollover bit set
631 */
632 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800633
634 if (reg->pfu_enabled)
635 card->txbd_rdptr = 0;
636 else
637 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700638
639 /* allocate shared memory for the BD ring and divide the same in to
640 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800641 if (reg->pfu_enabled)
642 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
643 MWIFIEX_MAX_TXRX_BD;
644 else
645 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
646 MWIFIEX_MAX_TXRX_BD;
647
Amitkumar Karward930fae2011-10-11 17:41:21 -0700648 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700649 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800650 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
651 card->txbd_ring_size,
652 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700653 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800654 dev_err(adapter->dev,
655 "allocate consistent memory (%d bytes) failed!\n",
656 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800657 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700658 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700659 dev_dbg(adapter->dev,
660 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800661 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700662 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700663
Avinash Patil07324842013-02-08 18:18:07 -0800664 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700665}
666
667static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
668{
669 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800670 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700671
Avinash Patil07324842013-02-08 18:18:07 -0800672 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700673
Avinash Patilfc331462013-01-03 21:21:30 -0800674 if (card->txbd_ring_vbase)
675 pci_free_consistent(card->dev, card->txbd_ring_size,
676 card->txbd_ring_vbase,
677 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700678 card->txbd_ring_size = 0;
679 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800680 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700681 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800682 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700683
684 return 0;
685}
686
687/*
688 * This function creates buffer descriptor ring for RX
689 */
690static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
691{
692 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800693 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700694
695 /*
696 * driver maintaines the read pointer and firmware maintaines the write
697 * pointer. The write pointer starts at 0 (zero) while the read pointer
698 * starts at zero with rollover bit set
699 */
700 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800701 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700702
Avinash Patilca8f2112013-02-08 18:18:09 -0800703 if (reg->pfu_enabled)
704 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
705 MWIFIEX_MAX_TXRX_BD;
706 else
707 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
708 MWIFIEX_MAX_TXRX_BD;
709
Amitkumar Karward930fae2011-10-11 17:41:21 -0700710 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700711 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800712 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
713 card->rxbd_ring_size,
714 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700715 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800716 dev_err(adapter->dev,
717 "allocate consistent memory (%d bytes) failed!\n",
718 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800719 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700720 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700721
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700722 dev_dbg(adapter->dev,
723 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
724 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
725 (u32)((u64)card->rxbd_ring_pbase >> 32),
726 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700727
Avinash Patil07324842013-02-08 18:18:07 -0800728 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700729}
730
731/*
732 * This function deletes Buffer descriptor ring for RX
733 */
734static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
735{
736 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800737 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700738
Avinash Patil07324842013-02-08 18:18:07 -0800739 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700740
Avinash Patilfc331462013-01-03 21:21:30 -0800741 if (card->rxbd_ring_vbase)
742 pci_free_consistent(card->dev, card->rxbd_ring_size,
743 card->rxbd_ring_vbase,
744 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700745 card->rxbd_ring_size = 0;
746 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800747 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700748 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800749 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700750
751 return 0;
752}
753
754/*
755 * This function creates buffer descriptor ring for Events
756 */
757static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
758{
759 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800760 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700761
762 /*
763 * driver maintaines the read pointer and firmware maintaines the write
764 * pointer. The write pointer starts at 0 (zero) while the read pointer
765 * starts at zero with rollover bit set
766 */
767 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800768 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700769
Avinash Patile05dc3e2013-02-08 18:18:08 -0800770 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800771 MWIFIEX_MAX_EVT_BD;
772
Amitkumar Karward930fae2011-10-11 17:41:21 -0700773 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700774 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800775 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
776 card->evtbd_ring_size,
777 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700778 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700779 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800780 "allocate consistent memory (%d bytes) failed!\n",
781 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800782 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700783 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700784
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700785 dev_dbg(adapter->dev,
786 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
787 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
788 (u32)((u64)card->evtbd_ring_pbase >> 32),
789 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700790
Avinash Patil07324842013-02-08 18:18:07 -0800791 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700792}
793
794/*
795 * This function deletes Buffer descriptor ring for Events
796 */
797static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
798{
799 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800800 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700801
Avinash Patil07324842013-02-08 18:18:07 -0800802 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700803
Avinash Patilfc331462013-01-03 21:21:30 -0800804 if (card->evtbd_ring_vbase)
805 pci_free_consistent(card->dev, card->evtbd_ring_size,
806 card->evtbd_ring_vbase,
807 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700808 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800809 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700810 card->evtbd_ring_size = 0;
811 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800812 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700813
814 return 0;
815}
816
817/*
818 * This function allocates a buffer for CMDRSP
819 */
820static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
821{
822 struct pcie_service_card *card = adapter->card;
823 struct sk_buff *skb;
824
825 /* Allocate memory for receiving command response data */
826 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
827 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700828 dev_err(adapter->dev,
829 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700830 return -ENOMEM;
831 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700832 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800833 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
834 PCI_DMA_FROMDEVICE))
835 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700836
Avinash Patilfc331462013-01-03 21:21:30 -0800837 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700838
839 return 0;
840}
841
842/*
843 * This function deletes a buffer for CMDRSP
844 */
845static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
846{
847 struct pcie_service_card *card;
Avinash Patilfc331462013-01-03 21:21:30 -0800848 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700849
850 if (!adapter)
851 return 0;
852
853 card = adapter->card;
854
Avinash Patilfc331462013-01-03 21:21:30 -0800855 if (card && card->cmdrsp_buf) {
856 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
857 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
858 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700859 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800860 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700861
Avinash Patilfc331462013-01-03 21:21:30 -0800862 if (card && card->cmd_buf) {
863 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
Yogesh Ashok Powar7af1ce02013-04-23 16:49:50 -0700864 pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len,
Avinash Patilfc331462013-01-03 21:21:30 -0800865 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800866 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700867 return 0;
868}
869
870/*
871 * This function allocates a buffer for sleep cookie
872 */
873static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
874{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700875 struct pcie_service_card *card = adapter->card;
876
Avinash Patilfc331462013-01-03 21:21:30 -0800877 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
878 &card->sleep_cookie_pbase);
879 if (!card->sleep_cookie_vbase) {
880 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700881 return -ENOMEM;
882 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700883 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800884 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700885
886 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800887 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700888
889 return 0;
890}
891
892/*
893 * This function deletes buffer for sleep cookie
894 */
895static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
896{
897 struct pcie_service_card *card;
898
899 if (!adapter)
900 return 0;
901
902 card = adapter->card;
903
Avinash Patilfc331462013-01-03 21:21:30 -0800904 if (card && card->sleep_cookie_vbase) {
905 pci_free_consistent(card->dev, sizeof(u32),
906 card->sleep_cookie_vbase,
907 card->sleep_cookie_pbase);
908 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700909 }
910
911 return 0;
912}
913
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800914/* This function flushes the TX buffer descriptor ring
915 * This function defined as handler is also called while cleaning TXRX
916 * during disconnect/ bss stop.
917 */
918static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
919{
920 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800921
Avinash Patil48f4d912013-02-20 21:12:58 -0800922 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800923 card->txbd_flush = 1;
924 /* write pointer already set at last send
925 * send dnld-rdy intr again, wait for completion.
926 */
927 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
928 CPU_INTR_DNLD_RDY)) {
929 dev_err(adapter->dev,
930 "failed to assert dnld-rdy interrupt.\n");
931 return -1;
932 }
933 }
934 return 0;
935}
936
Amitkumar Karward930fae2011-10-11 17:41:21 -0700937/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800938 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700939 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800940static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700941{
Avinash Patile7f767a2013-01-03 21:21:32 -0800942 struct sk_buff *skb;
943 dma_addr_t buf_pa;
Avinash Patilca8f2112013-02-08 18:18:09 -0800944 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800945 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800946 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700947 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800948 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700949
950 if (!mwifiex_pcie_ok_to_access_hw(adapter))
951 mwifiex_pm_wakeup_card(adapter);
952
953 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800954 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700955 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800956 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700957 return -1;
958 }
959
Avinash Patile7f767a2013-01-03 21:21:32 -0800960 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
961 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700962
Avinash Patilca8f2112013-02-08 18:18:09 -0800963 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800964 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800965 while (((card->txbd_rdptr & reg->tx_mask) !=
966 (rdptr & reg->tx_mask)) ||
967 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
968 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800969 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
970 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800971
972 skb = card->tx_buf_list[wrdoneidx];
973 if (skb) {
974 dev_dbg(adapter->dev,
975 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
976 skb, wrdoneidx);
977 MWIFIEX_SKB_PACB(skb, &buf_pa);
978 pci_unmap_single(card->dev, buf_pa, skb->len,
979 PCI_DMA_TODEVICE);
980
981 unmap_count++;
982
983 if (card->txbd_flush)
984 mwifiex_write_data_complete(adapter, skb, 0,
985 -1);
986 else
987 mwifiex_write_data_complete(adapter, skb, 0, 0);
988 }
989
990 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800991
992 if (reg->pfu_enabled) {
993 desc2 = (void *)card->txbd_ring[wrdoneidx];
994 memset(desc2, 0, sizeof(*desc2));
995 } else {
996 desc = card->txbd_ring[wrdoneidx];
997 memset(desc, 0, sizeof(*desc));
998 }
999 switch (card->dev->device) {
1000 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1001 card->txbd_rdptr++;
1002 break;
1003 case PCIE_DEVICE_ID_MARVELL_88W8897:
1004 card->txbd_rdptr += reg->ring_tx_start_ptr;
1005 break;
1006 }
1007
Avinash Patile7f767a2013-01-03 21:21:32 -08001008
Avinash Patildd04e6a2013-02-08 18:18:06 -08001009 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001010 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001011 reg->tx_rollover_ind) ^
1012 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001013 }
1014
1015 if (unmap_count)
1016 adapter->data_sent = false;
1017
1018 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001019 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001020 card->txbd_flush = 0;
1021 else
1022 mwifiex_clean_pcie_ring_buf(adapter);
1023 }
1024
1025 return 0;
1026}
1027
1028/* This function sends data buffer to device. First 4 bytes of payload
1029 * are filled with payload length and payload type. Then this payload
1030 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1031 * Download ready interrupt to FW is deffered if Tx ring is not full and
1032 * additional payload can be accomodated.
1033 */
1034static int
1035mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1036 struct mwifiex_tx_param *tx_param)
1037{
1038 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001039 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001040 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001041 int ret;
1042 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001043 struct mwifiex_pcie_buf_desc *desc = NULL;
1044 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001045 __le16 *tmp;
1046
1047 if (!(skb->data && skb->len)) {
1048 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1049 __func__, skb->data, skb->len);
1050 return -1;
1051 }
1052
1053 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1054 mwifiex_pm_wakeup_card(adapter);
1055
Avinash Patilca8f2112013-02-08 18:18:09 -08001056 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001057 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1058 card->txbd_rdptr, card->txbd_wrptr);
1059 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001060 u8 *payload;
1061
1062 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001063 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001064 tmp = (__le16 *)&payload[0];
1065 *tmp = cpu_to_le16((u16)skb->len);
1066 tmp = (__le16 *)&payload[2];
1067 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001068
1069 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
1070 PCI_DMA_TODEVICE))
1071 return -1;
1072
Avinash Patilca8f2112013-02-08 18:18:09 -08001073 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001074 MWIFIEX_SKB_PACB(skb, &buf_pa);
1075 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001076
Avinash Patilca8f2112013-02-08 18:18:09 -08001077 if (reg->pfu_enabled) {
1078 desc2 = (void *)card->txbd_ring[wrindx];
1079 desc2->paddr = buf_pa;
1080 desc2->len = (u16)skb->len;
1081 desc2->frag_len = (u16)skb->len;
1082 desc2->offset = 0;
1083 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1084 MWIFIEX_BD_FLAG_LAST_DESC;
1085 } else {
1086 desc = card->txbd_ring[wrindx];
1087 desc->paddr = buf_pa;
1088 desc->len = (u16)skb->len;
1089 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1090 MWIFIEX_BD_FLAG_LAST_DESC;
1091 }
1092
1093 switch (card->dev->device) {
1094 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1095 card->txbd_wrptr++;
1096 break;
1097 case PCIE_DEVICE_ID_MARVELL_88W8897:
1098 card->txbd_wrptr += reg->ring_tx_start_ptr;
1099 break;
1100 }
1101
1102 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001103 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001104 reg->tx_rollover_ind) ^
1105 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001106
Avinash Patilca8f2112013-02-08 18:18:09 -08001107 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001108 /* Write the TX ring write pointer in to reg->tx_wrptr */
1109 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001110 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001111 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001112 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001113 ret = -1;
1114 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001115 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001116 if ((mwifiex_pcie_txbd_not_full(card)) &&
1117 tx_param->next_pkt_len) {
1118 /* have more packets and TxBD still can hold more */
1119 dev_dbg(adapter->dev,
1120 "SEND DATA: delay dnld-rdy interrupt.\n");
1121 adapter->data_sent = false;
1122 } else {
1123 /* Send the TX ready interrupt */
1124 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1125 CPU_INTR_DNLD_RDY)) {
1126 dev_err(adapter->dev,
1127 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1128 ret = -1;
1129 goto done_unmap;
1130 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001131 }
1132 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001133 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001134 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001135 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001136 dev_dbg(adapter->dev,
1137 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001138 adapter->data_sent = true;
1139 /* Send the TX ready interrupt */
1140 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1141 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001142 dev_err(adapter->dev,
1143 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001144 return -EBUSY;
1145 }
1146
Avinash Patile7f767a2013-01-03 21:21:32 -08001147 return -EINPROGRESS;
1148done_unmap:
1149 MWIFIEX_SKB_PACB(skb, &buf_pa);
1150 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1151 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001152 if (reg->pfu_enabled)
1153 memset(desc2, 0, sizeof(*desc2));
1154 else
1155 memset(desc, 0, sizeof(*desc));
1156
Avinash Patile7f767a2013-01-03 21:21:32 -08001157 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001158}
1159
1160/*
1161 * This function handles received buffer ring and
1162 * dispatches packets to upper
1163 */
1164static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1165{
1166 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001167 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001168 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001169 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001170 int ret = 0;
1171 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001172 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001173 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001174
Avinash Patile7f767a2013-01-03 21:21:32 -08001175 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1176 mwifiex_pm_wakeup_card(adapter);
1177
Amitkumar Karward930fae2011-10-11 17:41:21 -07001178 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001179 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001180 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001181 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001182 ret = -1;
1183 goto done;
1184 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001185 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001186
Avinash Patildd04e6a2013-02-08 18:18:06 -08001187 while (((wrptr & reg->rx_mask) !=
1188 (card->rxbd_rdptr & reg->rx_mask)) ||
1189 ((wrptr & reg->rx_rollover_ind) ==
1190 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001191 struct sk_buff *skb_data;
1192 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001193 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001194
Avinash Patildd04e6a2013-02-08 18:18:06 -08001195 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001196 skb_data = card->rx_buf_list[rd_index];
1197
Amitkumar Karwaref8f92b2014-02-18 15:41:55 -08001198 /* If skb allocation was failed earlier for Rx packet,
1199 * rx_buf_list[rd_index] would have been left with a NULL.
1200 */
1201 if (!skb_data)
1202 return -ENOMEM;
1203
Avinash Patile7f767a2013-01-03 21:21:32 -08001204 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1205 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1206 PCI_DMA_FROMDEVICE);
1207 card->rx_buf_list[rd_index] = NULL;
1208
Amitkumar Karward930fae2011-10-11 17:41:21 -07001209 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001210 * first 2 bytes for len, next 2 bytes is for type
1211 */
1212 pkt_len = *((__le16 *)skb_data->data);
1213 rx_len = le16_to_cpu(pkt_len);
1214 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001215 dev_dbg(adapter->dev,
1216 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1217 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001218 skb_pull(skb_data, INTF_HEADER_LEN);
1219 mwifiex_handle_rx_packet(adapter, skb_data);
1220
1221 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001222 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001223 dev_err(adapter->dev,
1224 "Unable to allocate skb.\n");
1225 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001226 }
1227
Avinash Patile7f767a2013-01-03 21:21:32 -08001228 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1229 MWIFIEX_RX_DATA_BUF_SIZE,
1230 PCI_DMA_FROMDEVICE))
1231 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001232
Avinash Patile7f767a2013-01-03 21:21:32 -08001233 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1234
1235 dev_dbg(adapter->dev,
1236 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1237 skb_tmp, rd_index);
1238 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001239
1240 if (reg->pfu_enabled) {
1241 desc2 = (void *)card->rxbd_ring[rd_index];
1242 desc2->paddr = buf_pa;
1243 desc2->len = skb_tmp->len;
1244 desc2->frag_len = skb_tmp->len;
1245 desc2->offset = 0;
1246 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1247 } else {
1248 desc = card->rxbd_ring[rd_index];
1249 desc->paddr = buf_pa;
1250 desc->len = skb_tmp->len;
1251 desc->flags = 0;
1252 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001253
Avinash Patildd04e6a2013-02-08 18:18:06 -08001254 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001255 MWIFIEX_MAX_TXRX_BD) {
1256 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001257 reg->rx_rollover_ind) ^
1258 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001259 }
1260 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001261 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001262
Avinash Patilca8f2112013-02-08 18:18:09 -08001263 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001264 /* Write the RX ring read pointer in to reg->rx_rdptr */
1265 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001266 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001267 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001268 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001269 ret = -1;
1270 goto done;
1271 }
1272
1273 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001274 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001275 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001276 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001277 ret = -1;
1278 goto done;
1279 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001280 dev_dbg(adapter->dev,
1281 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001282 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001283 }
1284
1285done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001286 return ret;
1287}
1288
1289/*
1290 * This function downloads the boot command to device
1291 */
1292static int
1293mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1294{
Avinash Patilfc331462013-01-03 21:21:30 -08001295 dma_addr_t buf_pa;
1296 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001297 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001298
Avinash Patilfc331462013-01-03 21:21:30 -08001299 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001300 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001301 "Invalid parameter in %s <%p. len %d>\n",
1302 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001303 return -1;
1304 }
1305
Avinash Patilfc331462013-01-03 21:21:30 -08001306 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1307 return -1;
1308
1309 MWIFIEX_SKB_PACB(skb, &buf_pa);
1310
Avinash Patildd04e6a2013-02-08 18:18:06 -08001311 /* Write the lower 32bits of the physical address to low command
1312 * address scratch register
1313 */
1314 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001315 dev_err(adapter->dev,
1316 "%s: failed to write download command to boot code.\n",
1317 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001318 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1319 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001320 return -1;
1321 }
1322
Avinash Patildd04e6a2013-02-08 18:18:06 -08001323 /* Write the upper 32bits of the physical address to high command
1324 * address scratch register
1325 */
1326 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001327 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001328 dev_err(adapter->dev,
1329 "%s: failed to write download command to boot code.\n",
1330 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001331 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1332 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001333 return -1;
1334 }
1335
Avinash Patildd04e6a2013-02-08 18:18:06 -08001336 /* Write the command length to cmd_size scratch register */
1337 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001338 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001339 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001340 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001341 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1342 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001343 return -1;
1344 }
1345
1346 /* Ring the door bell */
1347 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1348 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001349 dev_err(adapter->dev,
1350 "%s: failed to assert door-bell intr\n", __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001351 pci_unmap_single(card->dev, buf_pa,
1352 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001353 return -1;
1354 }
1355
1356 return 0;
1357}
1358
Avinash Patilc6d1d872013-01-03 21:21:29 -08001359/* This function init rx port in firmware which in turn enables to receive data
1360 * from device before transmitting any packet.
1361 */
1362static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1363{
1364 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001365 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001366 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001367
Avinash Patildd04e6a2013-02-08 18:18:06 -08001368 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001369 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1370 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001371 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001372 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001373 return -1;
1374 }
1375 return 0;
1376}
1377
1378/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001379 */
1380static int
1381mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1382{
1383 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001384 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001385 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001386 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1387 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001388
1389 if (!(skb->data && skb->len)) {
1390 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001391 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001392 return -1;
1393 }
1394
1395 /* Make sure a command response buffer is available */
1396 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001397 dev_err(adapter->dev,
1398 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001399 return -EBUSY;
1400 }
1401
Avinash Patilfc331462013-01-03 21:21:30 -08001402 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1403 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001404
1405 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001406
1407 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1408 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1409
1410 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1411 return -1;
1412
1413 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001414
1415 /* To send a command, the driver will:
1416 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001417 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001418 2. Ring the door bell (i.e. set the door bell interrupt)
1419
1420 In response to door bell interrupt, the firmware will perform
1421 the DMA of the command packet (first header to obtain the total
1422 length and then rest of the command).
1423 */
1424
1425 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001426 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001427 /* Write the lower 32bits of the cmdrsp buffer physical
1428 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001429 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001430 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001431 dev_err(adapter->dev,
1432 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001433 ret = -1;
1434 goto done;
1435 }
1436 /* Write the upper 32bits of the cmdrsp buffer physical
1437 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001438 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001439 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001440 dev_err(adapter->dev,
1441 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001442 ret = -1;
1443 goto done;
1444 }
1445 }
1446
Avinash Patilfc331462013-01-03 21:21:30 -08001447 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001448 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1449 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1450 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001451 dev_err(adapter->dev,
1452 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001453 ret = -1;
1454 goto done;
1455 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001456 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1457 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001458 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001459 dev_err(adapter->dev,
1460 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001461 ret = -1;
1462 goto done;
1463 }
1464
Avinash Patildd04e6a2013-02-08 18:18:06 -08001465 /* Write the command length to reg->cmd_size */
1466 if (mwifiex_write_reg(adapter, reg->cmd_size,
1467 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001468 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001469 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001470 ret = -1;
1471 goto done;
1472 }
1473
1474 /* Ring the door bell */
1475 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1476 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001477 dev_err(adapter->dev,
1478 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001479 ret = -1;
1480 goto done;
1481 }
1482
1483done:
1484 if (ret)
1485 adapter->cmd_sent = false;
1486
1487 return 0;
1488}
1489
1490/*
1491 * This function handles command complete interrupt
1492 */
1493static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1494{
1495 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001496 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001497 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001498 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001499 u16 rx_len;
1500 __le16 pkt_len;
1501 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001502
1503 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1504
Avinash Patilfc331462013-01-03 21:21:30 -08001505 MWIFIEX_SKB_PACB(skb, &buf_pa);
1506 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1507 PCI_DMA_FROMDEVICE);
1508
1509 pkt_len = *((__le16 *)skb->data);
1510 rx_len = le16_to_cpu(pkt_len);
1511 skb_trim(skb, rx_len);
1512 skb_pull(skb, INTF_HEADER_LEN);
1513
Amitkumar Karward930fae2011-10-11 17:41:21 -07001514 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001515 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001516 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1517 skb->len);
Avinash Patil52301a82013-02-12 14:38:32 -08001518 while (reg->sleep_cookie && (count++ < 10) &&
1519 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001520 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001521 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001522 dev_err(adapter->dev,
1523 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001524 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001525 memcpy(adapter->upld_buf, skb->data,
1526 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001527 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001528 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1529 PCI_DMA_FROMDEVICE))
1530 return -1;
1531
1532 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001533 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001534 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001535 adapter->cmd_resp_received = true;
1536 /* Take the pointer and set it to CMD node and will
1537 return in the response complete callback */
1538 card->cmdrsp_buf = NULL;
1539
1540 /* Clear the cmd-rsp buffer address in scratch registers. This
1541 will prevent firmware from writing to the same response
1542 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001543 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001544 dev_err(adapter->dev,
1545 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001546 return -1;
1547 }
1548 /* Write the upper 32bits of the cmdrsp buffer physical
1549 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001550 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001551 dev_err(adapter->dev,
1552 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001553 return -1;
1554 }
1555 }
1556
1557 return 0;
1558}
1559
1560/*
1561 * Command Response processing complete handler
1562 */
1563static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1564 struct sk_buff *skb)
1565{
1566 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001567 dma_addr_t buf_pa;
1568 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001569
1570 if (skb) {
1571 card->cmdrsp_buf = skb;
1572 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001573 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1574 PCI_DMA_FROMDEVICE))
1575 return -1;
1576 }
1577
1578 skb_tmp = card->cmd_buf;
1579 if (skb_tmp) {
1580 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
Yogesh Ashok Powar7af1ce02013-04-23 16:49:50 -07001581 pci_unmap_single(card->dev, buf_pa, skb_tmp->len,
Avinash Patilfc331462013-01-03 21:21:30 -08001582 PCI_DMA_FROMDEVICE);
1583 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001584 }
1585
1586 return 0;
1587}
1588
1589/*
1590 * This function handles firmware event ready interrupt
1591 */
1592static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1593{
1594 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001595 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001596 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1597 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001598 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001599 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001600
1601 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1602 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001603
1604 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001605 dev_dbg(adapter->dev, "info: Event being processed, "
1606 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001607 return 0;
1608 }
1609
1610 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1611 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1612 return -1;
1613 }
1614
1615 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001616 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001617 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001618 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001619 return -1;
1620 }
1621
1622 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001623 card->evtbd_rdptr, wrptr);
1624 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1625 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001626 ((wrptr & reg->evt_rollover_ind) ==
1627 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001628 struct sk_buff *skb_cmd;
1629 __le16 data_len = 0;
1630 u16 evt_len;
1631
1632 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1633 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001634 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1635 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1636 PCI_DMA_FROMDEVICE);
1637
Amitkumar Karward930fae2011-10-11 17:41:21 -07001638 /* Take the pointer and set it to event pointer in adapter
1639 and will return back after event handling callback */
1640 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001641 desc = card->evtbd_ring[rdptr];
1642 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001643
1644 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1645 adapter->event_cause = event;
1646 /* The first 4bytes will be the event transfer header
1647 len is 2 bytes followed by type which is 2 bytes */
1648 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1649 evt_len = le16_to_cpu(data_len);
1650
1651 skb_pull(skb_cmd, INTF_HEADER_LEN);
1652 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1653
1654 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1655 memcpy(adapter->event_body, skb_cmd->data +
1656 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1657 MWIFIEX_EVENT_HEADER_LEN);
1658
1659 adapter->event_received = true;
1660 adapter->event_skb = skb_cmd;
1661
1662 /* Do not update the event read pointer here, wait till the
1663 buffer is released. This is just to make things simpler,
1664 we need to find a better method of managing these buffers.
1665 */
1666 }
1667
1668 return 0;
1669}
1670
1671/*
1672 * Event processing complete handler
1673 */
1674static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1675 struct sk_buff *skb)
1676{
1677 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001678 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001679 int ret = 0;
1680 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1681 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001682 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001683 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001684
1685 if (!skb)
1686 return 0;
1687
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001688 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001689 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001690 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001691 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001692 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001693
1694 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001695 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001696 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001697 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001698 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001699 }
1700
1701 if (!card->evt_buf_list[rdptr]) {
1702 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001703 if (mwifiex_map_pci_memory(adapter, skb,
1704 MAX_EVENT_SIZE,
1705 PCI_DMA_FROMDEVICE))
1706 return -1;
1707 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001708 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001709 MWIFIEX_SKB_PACB(skb, &buf_pa);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001710 desc = card->evtbd_ring[rdptr];
1711 desc->paddr = buf_pa;
1712 desc->len = (u16)skb->len;
1713 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001714 skb = NULL;
1715 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001716 dev_dbg(adapter->dev,
1717 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1718 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001719 }
1720
1721 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1722 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001723 reg->evt_rollover_ind) ^
1724 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001725 }
1726
1727 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001728 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001729
Avinash Patildd04e6a2013-02-08 18:18:06 -08001730 /* Write the event ring read pointer in to reg->evt_rdptr */
1731 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1732 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001733 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001734 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001735 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001736 }
1737
Amitkumar Karward930fae2011-10-11 17:41:21 -07001738 dev_dbg(adapter->dev, "info: Check Events Again\n");
1739 ret = mwifiex_pcie_process_event_ready(adapter);
1740
1741 return ret;
1742}
1743
1744/*
1745 * This function downloads the firmware to the card.
1746 *
1747 * Firmware is downloaded to the card in blocks. Every block download
1748 * is tested for CRC errors, and retried a number of times before
1749 * returning failure.
1750 */
1751static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1752 struct mwifiex_fw_image *fw)
1753{
1754 int ret;
1755 u8 *firmware = fw->fw_buf;
1756 u32 firmware_len = fw->fw_len;
1757 u32 offset = 0;
1758 struct sk_buff *skb;
1759 u32 txlen, tx_blocks = 0, tries, len;
1760 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001761 dma_addr_t buf_pa;
1762 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001763 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001764
1765 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001766 dev_err(adapter->dev,
1767 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001768 return -1;
1769 }
1770
1771 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001772 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001773
1774 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001775 dev_err(adapter->dev,
1776 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001777 return -1;
1778 }
1779
1780 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1781 if (!skb) {
1782 ret = -ENOMEM;
1783 goto done;
1784 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001785
1786 /* Perform firmware data transfer */
1787 do {
1788 u32 ireg_intr = 0;
1789
1790 /* More data? */
1791 if (offset >= firmware_len)
1792 break;
1793
1794 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001795 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001796 &len);
1797 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001798 dev_warn(adapter->dev,
1799 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001800 goto done;
1801 }
1802 if (len)
1803 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001804 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001805 }
1806
1807 if (!len) {
1808 break;
1809 } else if (len > MWIFIEX_UPLD_SIZE) {
1810 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001811 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001812 ret = -1;
1813 goto done;
1814 }
1815
1816 txlen = len;
1817
1818 if (len & BIT(0)) {
1819 block_retry_cnt++;
1820 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1821 pr_err("FW download failure @ %d, over max "
1822 "retry count\n", offset);
1823 ret = -1;
1824 goto done;
1825 }
1826 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001827 "helper: len = 0x%04X, txlen = %d\n",
1828 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001829 len &= ~BIT(0);
1830 /* Setting this to 0 to resend from same offset */
1831 txlen = 0;
1832 } else {
1833 block_retry_cnt = 0;
1834 /* Set blocksize to transfer - checking for
1835 last block */
1836 if (firmware_len - offset < txlen)
1837 txlen = firmware_len - offset;
1838
1839 dev_dbg(adapter->dev, ".");
1840
Avinash Patildd04e6a2013-02-08 18:18:06 -08001841 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1842 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001843
1844 /* Copy payload to buffer */
1845 memmove(skb->data, &firmware[offset], txlen);
1846 }
1847
1848 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001849 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001850
1851 /* Send the boot command to device */
1852 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001853 dev_err(adapter->dev,
1854 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001855 ret = -1;
1856 goto done;
1857 }
Avinash Patilfc331462013-01-03 21:21:30 -08001858
1859 MWIFIEX_SKB_PACB(skb, &buf_pa);
1860
Amitkumar Karward930fae2011-10-11 17:41:21 -07001861 /* Wait for the command done interrupt */
1862 do {
1863 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1864 &ireg_intr)) {
1865 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001866 "interrupt status during fw dnld.\n",
1867 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001868 pci_unmap_single(card->dev, buf_pa, skb->len,
1869 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001870 ret = -1;
1871 goto done;
1872 }
1873 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1874 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001875
1876 pci_unmap_single(card->dev, buf_pa, skb->len,
1877 PCI_DMA_TODEVICE);
1878
Amitkumar Karward930fae2011-10-11 17:41:21 -07001879 offset += txlen;
1880 } while (true);
1881
1882 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001883 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001884
1885 ret = 0;
1886
1887done:
1888 dev_kfree_skb_any(skb);
1889 return ret;
1890}
1891
1892/*
1893 * This function checks the firmware status in card.
1894 *
1895 * The winner interface is also determined by this function.
1896 */
1897static int
1898mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1899{
1900 int ret = 0;
1901 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001902 struct pcie_service_card *card = adapter->card;
1903 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001904 u32 tries;
1905
1906 /* Mask spurios interrupts */
1907 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001908 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001909 dev_warn(adapter->dev, "Write register failed\n");
1910 return -1;
1911 }
1912
1913 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001914 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1915 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001916 dev_err(adapter->dev,
1917 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001918 return -1;
1919 }
1920
1921 /* Wait for firmware initialization event */
1922 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001923 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001924 &firmware_stat))
1925 ret = -1;
1926 else
1927 ret = 0;
1928 if (ret)
1929 continue;
1930 if (firmware_stat == FIRMWARE_READY_PCIE) {
1931 ret = 0;
1932 break;
1933 } else {
1934 mdelay(100);
1935 ret = -1;
1936 }
1937 }
1938
1939 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001940 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001941 &winner_status))
1942 ret = -1;
1943 else if (!winner_status) {
1944 dev_err(adapter->dev, "PCI-E is the winner\n");
1945 adapter->winner = 1;
1946 ret = -1;
1947 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001948 dev_err(adapter->dev,
1949 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1950 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001951 ret = 0;
1952 }
1953 }
1954
1955 return ret;
1956}
1957
1958/*
1959 * This function reads the interrupt status from card.
1960 */
1961static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1962{
1963 u32 pcie_ireg;
1964 unsigned long flags;
1965
1966 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1967 return;
1968
1969 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1970 dev_warn(adapter->dev, "Read register failed\n");
1971 return;
1972 }
1973
1974 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1975
1976 mwifiex_pcie_disable_host_int(adapter);
1977
1978 /* Clear the pending interrupts */
1979 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1980 ~pcie_ireg)) {
1981 dev_warn(adapter->dev, "Write register failed\n");
1982 return;
1983 }
1984 spin_lock_irqsave(&adapter->int_lock, flags);
1985 adapter->int_status |= pcie_ireg;
1986 spin_unlock_irqrestore(&adapter->int_lock, flags);
1987
1988 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1989 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1990 (adapter->ps_state == PS_STATE_SLEEP)) {
1991 mwifiex_pcie_enable_host_int(adapter);
1992 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001993 PCIE_CPU_INT_EVENT,
1994 CPU_INTR_SLEEP_CFM_DONE)
1995 ) {
1996 dev_warn(adapter->dev,
1997 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001998 return;
1999
2000 }
2001 }
2002 } else if (!adapter->pps_uapsd_mode &&
Avinash Patilc24d9922013-03-22 21:49:06 -07002003 adapter->ps_state == PS_STATE_SLEEP &&
2004 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002005 /* Potentially for PCIe we could get other
2006 * interrupts like shared. Don't change power
2007 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002008 adapter->ps_state = PS_STATE_AWAKE;
2009 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002010 }
2011 }
2012}
2013
2014/*
2015 * Interrupt handler for PCIe root port
2016 *
2017 * This function reads the interrupt status from firmware and assigns
2018 * the main process in workqueue which will handle the interrupt.
2019 */
2020static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2021{
2022 struct pci_dev *pdev = (struct pci_dev *)context;
2023 struct pcie_service_card *card;
2024 struct mwifiex_adapter *adapter;
2025
2026 if (!pdev) {
2027 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2028 goto exit;
2029 }
2030
2031 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
2032 if (!card || !card->adapter) {
2033 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002034 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002035 goto exit;
2036 }
2037 adapter = card->adapter;
2038
2039 if (adapter->surprise_removed)
2040 goto exit;
2041
2042 mwifiex_interrupt_status(adapter);
2043 queue_work(adapter->workqueue, &adapter->main_work);
2044
2045exit:
2046 return IRQ_HANDLED;
2047}
2048
2049/*
2050 * This function checks the current interrupt status.
2051 *
2052 * The following interrupts are checked and handled by this function -
2053 * - Data sent
2054 * - Command sent
2055 * - Command received
2056 * - Packets received
2057 * - Events received
2058 *
2059 * In case of Rx packets received, the packets are uploaded from card to
2060 * host and processed accordingly.
2061 */
2062static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2063{
2064 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002065 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002066 unsigned long flags;
2067
2068 spin_lock_irqsave(&adapter->int_lock, flags);
2069 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002070 pcie_ireg = adapter->int_status;
2071 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002072 spin_unlock_irqrestore(&adapter->int_lock, flags);
2073
Avinash Patil659c4782013-01-03 21:21:28 -08002074 while (pcie_ireg & HOST_INTR_MASK) {
2075 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2076 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002077 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2078 ret = mwifiex_pcie_send_data_complete(adapter);
2079 if (ret)
2080 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002081 }
Avinash Patil659c4782013-01-03 21:21:28 -08002082 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2083 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002084 dev_dbg(adapter->dev, "info: Rx DATA\n");
2085 ret = mwifiex_pcie_process_recv_data(adapter);
2086 if (ret)
2087 return ret;
2088 }
Avinash Patil659c4782013-01-03 21:21:28 -08002089 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2090 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002091 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2092 ret = mwifiex_pcie_process_event_ready(adapter);
2093 if (ret)
2094 return ret;
2095 }
2096
Avinash Patil659c4782013-01-03 21:21:28 -08002097 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2098 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002099 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002100 dev_dbg(adapter->dev,
2101 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002102 adapter->cmd_sent = false;
2103 }
2104 /* Handle command response */
2105 ret = mwifiex_pcie_process_cmd_complete(adapter);
2106 if (ret)
2107 return ret;
2108 }
2109
2110 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2111 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2112 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002113 dev_warn(adapter->dev,
2114 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002115 return -1;
2116 }
2117
2118 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2119 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002120 PCIE_HOST_INT_STATUS,
2121 ~pcie_ireg)) {
2122 dev_warn(adapter->dev,
2123 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002124 return -1;
2125 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002126 }
2127
2128 }
2129 }
2130 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002131 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002132 if (adapter->ps_state != PS_STATE_SLEEP)
2133 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002134
2135 return 0;
2136}
2137
2138/*
2139 * This function downloads data from driver to card.
2140 *
2141 * Both commands and data packets are transferred to the card by this
2142 * function.
2143 *
2144 * This function adds the PCIE specific header to the front of the buffer
2145 * before transferring. The header contains the length of the packet and
2146 * the type. The firmware handles the packets based upon this set type.
2147 */
2148static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2149 struct sk_buff *skb,
2150 struct mwifiex_tx_param *tx_param)
2151{
Dan Carpenterfa161cb72011-11-07 19:31:45 -08002152 if (!skb) {
2153 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002154 return -1;
2155 }
2156
2157 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002158 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002159 else if (type == MWIFIEX_TYPE_CMD)
2160 return mwifiex_pcie_send_cmd(adapter, skb);
2161
2162 return 0;
2163}
2164
2165/*
2166 * This function initializes the PCI-E host memory space, WCB rings, etc.
2167 *
2168 * The following initializations steps are followed -
2169 * - Allocate TXBD ring buffers
2170 * - Allocate RXBD ring buffers
2171 * - Allocate event BD ring buffers
2172 * - Allocate command response ring buffer
2173 * - Allocate sleep cookie buffer
2174 */
2175static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2176{
2177 struct pcie_service_card *card = adapter->card;
2178 int ret;
2179 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002180 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002181
2182 pci_set_drvdata(pdev, card);
2183
2184 ret = pci_enable_device(pdev);
2185 if (ret)
2186 goto err_enable_dev;
2187
2188 pci_set_master(pdev);
2189
2190 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2191 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2192 if (ret) {
2193 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2194 goto err_set_dma_mask;
2195 }
2196
2197 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2198 if (ret) {
2199 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2200 goto err_set_dma_mask;
2201 }
2202
2203 ret = pci_request_region(pdev, 0, DRV_NAME);
2204 if (ret) {
2205 dev_err(adapter->dev, "req_reg(0) error\n");
2206 goto err_req_region0;
2207 }
2208 card->pci_mmap = pci_iomap(pdev, 0, 0);
2209 if (!card->pci_mmap) {
2210 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002211 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002212 goto err_iomap0;
2213 }
2214 ret = pci_request_region(pdev, 2, DRV_NAME);
2215 if (ret) {
2216 dev_err(adapter->dev, "req_reg(2) error\n");
2217 goto err_req_region2;
2218 }
2219 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2220 if (!card->pci_mmap1) {
2221 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002222 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002223 goto err_iomap2;
2224 }
2225
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002226 dev_dbg(adapter->dev,
2227 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2228 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002229
2230 card->cmdrsp_buf = NULL;
2231 ret = mwifiex_pcie_create_txbd_ring(adapter);
2232 if (ret)
2233 goto err_cre_txbd;
2234 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2235 if (ret)
2236 goto err_cre_rxbd;
2237 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2238 if (ret)
2239 goto err_cre_evtbd;
2240 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2241 if (ret)
2242 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002243 if (reg->sleep_cookie) {
2244 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2245 if (ret)
2246 goto err_alloc_cookie;
2247 } else {
2248 card->sleep_cookie_vbase = NULL;
2249 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002250 return ret;
2251
2252err_alloc_cookie:
2253 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2254err_alloc_cmdbuf:
2255 mwifiex_pcie_delete_evtbd_ring(adapter);
2256err_cre_evtbd:
2257 mwifiex_pcie_delete_rxbd_ring(adapter);
2258err_cre_rxbd:
2259 mwifiex_pcie_delete_txbd_ring(adapter);
2260err_cre_txbd:
2261 pci_iounmap(pdev, card->pci_mmap1);
2262err_iomap2:
2263 pci_release_region(pdev, 2);
2264err_req_region2:
2265 pci_iounmap(pdev, card->pci_mmap);
2266err_iomap0:
2267 pci_release_region(pdev, 0);
2268err_req_region0:
2269err_set_dma_mask:
2270 pci_disable_device(pdev);
2271err_enable_dev:
2272 pci_set_drvdata(pdev, NULL);
2273 return ret;
2274}
2275
2276/*
2277 * This function cleans up the allocated card buffers.
2278 *
2279 * The following are freed by this function -
2280 * - TXBD ring buffers
2281 * - RXBD ring buffers
2282 * - Event BD ring buffers
2283 * - Command response ring buffer
2284 * - Sleep cookie buffer
2285 */
2286static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2287{
2288 struct pcie_service_card *card = adapter->card;
2289 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002290 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002291
Amitkumar Karward930fae2011-10-11 17:41:21 -07002292 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002293 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002294 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002295 dev_err(adapter->dev,
2296 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002297 }
2298
2299 if (pdev) {
2300 pci_iounmap(pdev, card->pci_mmap);
2301 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002302 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002303 pci_release_region(pdev, 2);
2304 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002305 pci_set_drvdata(pdev, NULL);
2306 }
2307}
2308
2309/*
2310 * This function registers the PCIE device.
2311 *
2312 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2313 */
2314static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2315{
2316 int ret;
2317 struct pcie_service_card *card = adapter->card;
2318 struct pci_dev *pdev = card->dev;
2319
2320 /* save adapter pointer in card */
2321 card->adapter = adapter;
2322
2323 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2324 "MRVL_PCIE", pdev);
2325 if (ret) {
2326 pr_err("request_irq failed: ret=%d\n", ret);
2327 adapter->card = NULL;
2328 return -1;
2329 }
2330
2331 adapter->dev = &pdev->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002332 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002333
2334 return 0;
2335}
2336
2337/*
2338 * This function unregisters the PCIE device.
2339 *
2340 * The PCIE IRQ is released, the function is disabled and driver
2341 * data is set to null.
2342 */
2343static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2344{
2345 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002346 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002347
2348 if (card) {
2349 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2350 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002351
Avinash Patil52301a82013-02-12 14:38:32 -08002352 reg = card->pcie.reg;
2353 if (reg->sleep_cookie)
2354 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2355
Avinash Patilfc331462013-01-03 21:21:30 -08002356 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2357 mwifiex_pcie_delete_evtbd_ring(adapter);
2358 mwifiex_pcie_delete_rxbd_ring(adapter);
2359 mwifiex_pcie_delete_txbd_ring(adapter);
2360 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002361 }
2362}
2363
2364static struct mwifiex_if_ops pcie_ops = {
2365 .init_if = mwifiex_pcie_init,
2366 .cleanup_if = mwifiex_pcie_cleanup,
2367 .check_fw_status = mwifiex_check_fw_status,
2368 .prog_fw = mwifiex_prog_fw_w_helper,
2369 .register_dev = mwifiex_register_dev,
2370 .unregister_dev = mwifiex_unregister_dev,
2371 .enable_int = mwifiex_pcie_enable_host_int,
2372 .process_int_status = mwifiex_process_int_status,
2373 .host_to_card = mwifiex_pcie_host_to_card,
2374 .wakeup = mwifiex_pm_wakeup_card,
2375 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2376
2377 /* PCIE specific */
2378 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2379 .event_complete = mwifiex_pcie_event_complete,
2380 .update_mp_end_port = NULL,
2381 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002382 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002383 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002384};
2385
2386/*
2387 * This function initializes the PCIE driver module.
2388 *
2389 * This initiates the semaphore and registers the device with
2390 * PCIE bus.
2391 */
2392static int mwifiex_pcie_init_module(void)
2393{
2394 int ret;
2395
Avinash Patilca8f2112013-02-08 18:18:09 -08002396 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002397
2398 sema_init(&add_remove_card_sem, 1);
2399
2400 /* Clear the flag in case user removes the card. */
2401 user_rmmod = 0;
2402
2403 ret = pci_register_driver(&mwifiex_pcie);
2404 if (ret)
2405 pr_err("Driver register failed!\n");
2406 else
2407 pr_debug("info: Driver registered successfully!\n");
2408
2409 return ret;
2410}
2411
2412/*
2413 * This function cleans up the PCIE driver.
2414 *
2415 * The following major steps are followed for cleanup -
2416 * - Resume the device if its suspended
2417 * - Disconnect the device if connected
2418 * - Shutdown the firmware
2419 * - Unregister the device from PCIE bus.
2420 */
2421static void mwifiex_pcie_cleanup_module(void)
2422{
2423 if (!down_interruptible(&add_remove_card_sem))
2424 up(&add_remove_card_sem);
2425
2426 /* Set the flag as user is removing this module. */
2427 user_rmmod = 1;
2428
2429 pci_unregister_driver(&mwifiex_pcie);
2430}
2431
2432module_init(mwifiex_pcie_init_module);
2433module_exit(mwifiex_pcie_cleanup_module);
2434
2435MODULE_AUTHOR("Marvell International Ltd.");
2436MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2437MODULE_VERSION(PCIE_VERSION);
2438MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002439MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2440MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);