blob: b5ff9f1f69c5b63b89c09f1ebd7f6141f1531fd8 [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,
575 skb->len, PCI_DMA_TODEVICE);
576 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,
584 skb->len, PCI_DMA_TODEVICE);
585 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);
864 pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER,
865 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700866 dev_kfree_skb_any(card->cmd_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800867 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700868 return 0;
869}
870
871/*
872 * This function allocates a buffer for sleep cookie
873 */
874static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
875{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700876 struct pcie_service_card *card = adapter->card;
877
Avinash Patilfc331462013-01-03 21:21:30 -0800878 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
879 &card->sleep_cookie_pbase);
880 if (!card->sleep_cookie_vbase) {
881 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700882 return -ENOMEM;
883 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700884 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800885 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700886
887 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800888 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700889
890 return 0;
891}
892
893/*
894 * This function deletes buffer for sleep cookie
895 */
896static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
897{
898 struct pcie_service_card *card;
899
900 if (!adapter)
901 return 0;
902
903 card = adapter->card;
904
Avinash Patilfc331462013-01-03 21:21:30 -0800905 if (card && card->sleep_cookie_vbase) {
906 pci_free_consistent(card->dev, sizeof(u32),
907 card->sleep_cookie_vbase,
908 card->sleep_cookie_pbase);
909 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700910 }
911
912 return 0;
913}
914
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800915/* This function flushes the TX buffer descriptor ring
916 * This function defined as handler is also called while cleaning TXRX
917 * during disconnect/ bss stop.
918 */
919static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
920{
921 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800922
Avinash Patil48f4d912013-02-20 21:12:58 -0800923 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800924 card->txbd_flush = 1;
925 /* write pointer already set at last send
926 * send dnld-rdy intr again, wait for completion.
927 */
928 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
929 CPU_INTR_DNLD_RDY)) {
930 dev_err(adapter->dev,
931 "failed to assert dnld-rdy interrupt.\n");
932 return -1;
933 }
934 }
935 return 0;
936}
937
Amitkumar Karward930fae2011-10-11 17:41:21 -0700938/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800939 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700940 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800941static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700942{
Avinash Patile7f767a2013-01-03 21:21:32 -0800943 struct sk_buff *skb;
944 dma_addr_t buf_pa;
Avinash Patilca8f2112013-02-08 18:18:09 -0800945 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800946 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800947 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700948 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800949 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700950
951 if (!mwifiex_pcie_ok_to_access_hw(adapter))
952 mwifiex_pm_wakeup_card(adapter);
953
954 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800955 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700956 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800957 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700958 return -1;
959 }
960
Avinash Patile7f767a2013-01-03 21:21:32 -0800961 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
962 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700963
Avinash Patilca8f2112013-02-08 18:18:09 -0800964 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800965 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800966 while (((card->txbd_rdptr & reg->tx_mask) !=
967 (rdptr & reg->tx_mask)) ||
968 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
969 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800970 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
971 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800972
973 skb = card->tx_buf_list[wrdoneidx];
974 if (skb) {
975 dev_dbg(adapter->dev,
976 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
977 skb, wrdoneidx);
978 MWIFIEX_SKB_PACB(skb, &buf_pa);
979 pci_unmap_single(card->dev, buf_pa, skb->len,
980 PCI_DMA_TODEVICE);
981
982 unmap_count++;
983
984 if (card->txbd_flush)
985 mwifiex_write_data_complete(adapter, skb, 0,
986 -1);
987 else
988 mwifiex_write_data_complete(adapter, skb, 0, 0);
989 }
990
991 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800992
993 if (reg->pfu_enabled) {
994 desc2 = (void *)card->txbd_ring[wrdoneidx];
995 memset(desc2, 0, sizeof(*desc2));
996 } else {
997 desc = card->txbd_ring[wrdoneidx];
998 memset(desc, 0, sizeof(*desc));
999 }
1000 switch (card->dev->device) {
1001 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1002 card->txbd_rdptr++;
1003 break;
1004 case PCIE_DEVICE_ID_MARVELL_88W8897:
1005 card->txbd_rdptr += reg->ring_tx_start_ptr;
1006 break;
1007 }
1008
Avinash Patile7f767a2013-01-03 21:21:32 -08001009
Avinash Patildd04e6a2013-02-08 18:18:06 -08001010 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001011 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001012 reg->tx_rollover_ind) ^
1013 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001014 }
1015
1016 if (unmap_count)
1017 adapter->data_sent = false;
1018
1019 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001020 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001021 card->txbd_flush = 0;
1022 else
1023 mwifiex_clean_pcie_ring_buf(adapter);
1024 }
1025
1026 return 0;
1027}
1028
1029/* This function sends data buffer to device. First 4 bytes of payload
1030 * are filled with payload length and payload type. Then this payload
1031 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1032 * Download ready interrupt to FW is deffered if Tx ring is not full and
1033 * additional payload can be accomodated.
1034 */
1035static int
1036mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1037 struct mwifiex_tx_param *tx_param)
1038{
1039 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001040 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001041 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001042 int ret;
1043 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001044 struct mwifiex_pcie_buf_desc *desc = NULL;
1045 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001046 __le16 *tmp;
1047
1048 if (!(skb->data && skb->len)) {
1049 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1050 __func__, skb->data, skb->len);
1051 return -1;
1052 }
1053
1054 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1055 mwifiex_pm_wakeup_card(adapter);
1056
Avinash Patilca8f2112013-02-08 18:18:09 -08001057 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001058 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1059 card->txbd_rdptr, card->txbd_wrptr);
1060 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001061 u8 *payload;
1062
1063 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001064 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001065 tmp = (__le16 *)&payload[0];
1066 *tmp = cpu_to_le16((u16)skb->len);
1067 tmp = (__le16 *)&payload[2];
1068 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001069
1070 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
1071 PCI_DMA_TODEVICE))
1072 return -1;
1073
Avinash Patilca8f2112013-02-08 18:18:09 -08001074 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001075 MWIFIEX_SKB_PACB(skb, &buf_pa);
1076 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001077
Avinash Patilca8f2112013-02-08 18:18:09 -08001078 if (reg->pfu_enabled) {
1079 desc2 = (void *)card->txbd_ring[wrindx];
1080 desc2->paddr = buf_pa;
1081 desc2->len = (u16)skb->len;
1082 desc2->frag_len = (u16)skb->len;
1083 desc2->offset = 0;
1084 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1085 MWIFIEX_BD_FLAG_LAST_DESC;
1086 } else {
1087 desc = card->txbd_ring[wrindx];
1088 desc->paddr = buf_pa;
1089 desc->len = (u16)skb->len;
1090 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1091 MWIFIEX_BD_FLAG_LAST_DESC;
1092 }
1093
1094 switch (card->dev->device) {
1095 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1096 card->txbd_wrptr++;
1097 break;
1098 case PCIE_DEVICE_ID_MARVELL_88W8897:
1099 card->txbd_wrptr += reg->ring_tx_start_ptr;
1100 break;
1101 }
1102
1103 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001104 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001105 reg->tx_rollover_ind) ^
1106 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001107
Avinash Patilca8f2112013-02-08 18:18:09 -08001108 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001109 /* Write the TX ring write pointer in to reg->tx_wrptr */
1110 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001111 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001112 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001113 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001114 ret = -1;
1115 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001116 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001117 if ((mwifiex_pcie_txbd_not_full(card)) &&
1118 tx_param->next_pkt_len) {
1119 /* have more packets and TxBD still can hold more */
1120 dev_dbg(adapter->dev,
1121 "SEND DATA: delay dnld-rdy interrupt.\n");
1122 adapter->data_sent = false;
1123 } else {
1124 /* Send the TX ready interrupt */
1125 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1126 CPU_INTR_DNLD_RDY)) {
1127 dev_err(adapter->dev,
1128 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1129 ret = -1;
1130 goto done_unmap;
1131 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001132 }
1133 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001134 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001135 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001136 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001137 dev_dbg(adapter->dev,
1138 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001139 adapter->data_sent = true;
1140 /* Send the TX ready interrupt */
1141 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1142 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001143 dev_err(adapter->dev,
1144 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001145 return -EBUSY;
1146 }
1147
Avinash Patile7f767a2013-01-03 21:21:32 -08001148 return -EINPROGRESS;
1149done_unmap:
1150 MWIFIEX_SKB_PACB(skb, &buf_pa);
1151 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1152 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001153 if (reg->pfu_enabled)
1154 memset(desc2, 0, sizeof(*desc2));
1155 else
1156 memset(desc, 0, sizeof(*desc));
1157
Avinash Patile7f767a2013-01-03 21:21:32 -08001158 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001159}
1160
1161/*
1162 * This function handles received buffer ring and
1163 * dispatches packets to upper
1164 */
1165static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1166{
1167 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001168 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001169 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001170 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001171 int ret = 0;
1172 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001173 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001174 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001175
Avinash Patile7f767a2013-01-03 21:21:32 -08001176 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1177 mwifiex_pm_wakeup_card(adapter);
1178
Amitkumar Karward930fae2011-10-11 17:41:21 -07001179 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001180 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001181 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001182 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001183 ret = -1;
1184 goto done;
1185 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001186 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001187
Avinash Patildd04e6a2013-02-08 18:18:06 -08001188 while (((wrptr & reg->rx_mask) !=
1189 (card->rxbd_rdptr & reg->rx_mask)) ||
1190 ((wrptr & reg->rx_rollover_ind) ==
1191 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001192 struct sk_buff *skb_data;
1193 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001194 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001195
Avinash Patildd04e6a2013-02-08 18:18:06 -08001196 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001197 skb_data = card->rx_buf_list[rd_index];
1198
Avinash Patile7f767a2013-01-03 21:21:32 -08001199 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1200 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1201 PCI_DMA_FROMDEVICE);
1202 card->rx_buf_list[rd_index] = NULL;
1203
Amitkumar Karward930fae2011-10-11 17:41:21 -07001204 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001205 * first 2 bytes for len, next 2 bytes is for type
1206 */
1207 pkt_len = *((__le16 *)skb_data->data);
1208 rx_len = le16_to_cpu(pkt_len);
1209 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001210 dev_dbg(adapter->dev,
1211 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1212 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001213 skb_pull(skb_data, INTF_HEADER_LEN);
1214 mwifiex_handle_rx_packet(adapter, skb_data);
1215
1216 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001217 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001218 dev_err(adapter->dev,
1219 "Unable to allocate skb.\n");
1220 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001221 }
1222
Avinash Patile7f767a2013-01-03 21:21:32 -08001223 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1224 MWIFIEX_RX_DATA_BUF_SIZE,
1225 PCI_DMA_FROMDEVICE))
1226 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001227
Avinash Patile7f767a2013-01-03 21:21:32 -08001228 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1229
1230 dev_dbg(adapter->dev,
1231 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1232 skb_tmp, rd_index);
1233 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001234
1235 if (reg->pfu_enabled) {
1236 desc2 = (void *)card->rxbd_ring[rd_index];
1237 desc2->paddr = buf_pa;
1238 desc2->len = skb_tmp->len;
1239 desc2->frag_len = skb_tmp->len;
1240 desc2->offset = 0;
1241 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1242 } else {
1243 desc = card->rxbd_ring[rd_index];
1244 desc->paddr = buf_pa;
1245 desc->len = skb_tmp->len;
1246 desc->flags = 0;
1247 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001248
Avinash Patildd04e6a2013-02-08 18:18:06 -08001249 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001250 MWIFIEX_MAX_TXRX_BD) {
1251 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001252 reg->rx_rollover_ind) ^
1253 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001254 }
1255 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001256 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001257
Avinash Patilca8f2112013-02-08 18:18:09 -08001258 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001259 /* Write the RX ring read pointer in to reg->rx_rdptr */
1260 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001261 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001262 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001263 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001264 ret = -1;
1265 goto done;
1266 }
1267
1268 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001269 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001270 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001271 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001272 ret = -1;
1273 goto done;
1274 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001275 dev_dbg(adapter->dev,
1276 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001277 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001278 }
1279
1280done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001281 return ret;
1282}
1283
1284/*
1285 * This function downloads the boot command to device
1286 */
1287static int
1288mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1289{
Avinash Patilfc331462013-01-03 21:21:30 -08001290 dma_addr_t buf_pa;
1291 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001292 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001293
Avinash Patilfc331462013-01-03 21:21:30 -08001294 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001295 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001296 "Invalid parameter in %s <%p. len %d>\n",
1297 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001298 return -1;
1299 }
1300
Avinash Patilfc331462013-01-03 21:21:30 -08001301 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1302 return -1;
1303
1304 MWIFIEX_SKB_PACB(skb, &buf_pa);
1305
Avinash Patildd04e6a2013-02-08 18:18:06 -08001306 /* Write the lower 32bits of the physical address to low command
1307 * address scratch register
1308 */
1309 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001310 dev_err(adapter->dev,
1311 "%s: failed to write download command to boot code.\n",
1312 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001313 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1314 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001315 return -1;
1316 }
1317
Avinash Patildd04e6a2013-02-08 18:18:06 -08001318 /* Write the upper 32bits of the physical address to high command
1319 * address scratch register
1320 */
1321 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001322 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001323 dev_err(adapter->dev,
1324 "%s: failed to write download command to boot code.\n",
1325 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001326 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1327 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001328 return -1;
1329 }
1330
Avinash Patildd04e6a2013-02-08 18:18:06 -08001331 /* Write the command length to cmd_size scratch register */
1332 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001333 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001334 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001335 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001336 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1337 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001338 return -1;
1339 }
1340
1341 /* Ring the door bell */
1342 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1343 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001344 dev_err(adapter->dev,
1345 "%s: failed to assert door-bell intr\n", __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001346 pci_unmap_single(card->dev, buf_pa,
1347 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001348 return -1;
1349 }
1350
1351 return 0;
1352}
1353
Avinash Patilc6d1d872013-01-03 21:21:29 -08001354/* This function init rx port in firmware which in turn enables to receive data
1355 * from device before transmitting any packet.
1356 */
1357static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1358{
1359 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001360 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001361 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001362
Avinash Patildd04e6a2013-02-08 18:18:06 -08001363 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001364 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1365 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001366 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001367 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001368 return -1;
1369 }
1370 return 0;
1371}
1372
1373/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001374 */
1375static int
1376mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1377{
1378 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001379 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001380 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001381 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1382 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001383
1384 if (!(skb->data && skb->len)) {
1385 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001386 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001387 return -1;
1388 }
1389
1390 /* Make sure a command response buffer is available */
1391 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001392 dev_err(adapter->dev,
1393 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001394 return -EBUSY;
1395 }
1396
Avinash Patilfc331462013-01-03 21:21:30 -08001397 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1398 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001399
1400 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001401
1402 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1403 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1404
1405 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1406 return -1;
1407
1408 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001409
1410 /* To send a command, the driver will:
1411 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001412 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001413 2. Ring the door bell (i.e. set the door bell interrupt)
1414
1415 In response to door bell interrupt, the firmware will perform
1416 the DMA of the command packet (first header to obtain the total
1417 length and then rest of the command).
1418 */
1419
1420 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001421 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001422 /* Write the lower 32bits of the cmdrsp buffer physical
1423 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001424 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001425 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001426 dev_err(adapter->dev,
1427 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001428 ret = -1;
1429 goto done;
1430 }
1431 /* Write the upper 32bits of the cmdrsp buffer physical
1432 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001433 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001434 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001435 dev_err(adapter->dev,
1436 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001437 ret = -1;
1438 goto done;
1439 }
1440 }
1441
Avinash Patilfc331462013-01-03 21:21:30 -08001442 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001443 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1444 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1445 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001446 dev_err(adapter->dev,
1447 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001448 ret = -1;
1449 goto done;
1450 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001451 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1452 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001453 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001454 dev_err(adapter->dev,
1455 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001456 ret = -1;
1457 goto done;
1458 }
1459
Avinash Patildd04e6a2013-02-08 18:18:06 -08001460 /* Write the command length to reg->cmd_size */
1461 if (mwifiex_write_reg(adapter, reg->cmd_size,
1462 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001463 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001464 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001465 ret = -1;
1466 goto done;
1467 }
1468
1469 /* Ring the door bell */
1470 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1471 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001472 dev_err(adapter->dev,
1473 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001474 ret = -1;
1475 goto done;
1476 }
1477
1478done:
1479 if (ret)
1480 adapter->cmd_sent = false;
1481
1482 return 0;
1483}
1484
1485/*
1486 * This function handles command complete interrupt
1487 */
1488static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1489{
1490 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001491 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001492 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001493 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001494 u16 rx_len;
1495 __le16 pkt_len;
1496 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001497
1498 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1499
Avinash Patilfc331462013-01-03 21:21:30 -08001500 MWIFIEX_SKB_PACB(skb, &buf_pa);
1501 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1502 PCI_DMA_FROMDEVICE);
1503
1504 pkt_len = *((__le16 *)skb->data);
1505 rx_len = le16_to_cpu(pkt_len);
1506 skb_trim(skb, rx_len);
1507 skb_pull(skb, INTF_HEADER_LEN);
1508
Amitkumar Karward930fae2011-10-11 17:41:21 -07001509 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001510 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001511 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1512 skb->len);
Avinash Patil52301a82013-02-12 14:38:32 -08001513 while (reg->sleep_cookie && (count++ < 10) &&
1514 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001515 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001516 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001517 dev_err(adapter->dev,
1518 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001519 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001520 memcpy(adapter->upld_buf, skb->data,
1521 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patilfc331462013-01-03 21:21:30 -08001522 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1523 PCI_DMA_FROMDEVICE))
1524 return -1;
1525
1526 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001527 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001528 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001529 adapter->cmd_resp_received = true;
1530 /* Take the pointer and set it to CMD node and will
1531 return in the response complete callback */
1532 card->cmdrsp_buf = NULL;
1533
1534 /* Clear the cmd-rsp buffer address in scratch registers. This
1535 will prevent firmware from writing to the same response
1536 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001537 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001538 dev_err(adapter->dev,
1539 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001540 return -1;
1541 }
1542 /* Write the upper 32bits of the cmdrsp buffer physical
1543 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001544 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001545 dev_err(adapter->dev,
1546 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001547 return -1;
1548 }
1549 }
1550
1551 return 0;
1552}
1553
1554/*
1555 * Command Response processing complete handler
1556 */
1557static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1558 struct sk_buff *skb)
1559{
1560 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001561 dma_addr_t buf_pa;
1562 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001563
1564 if (skb) {
1565 card->cmdrsp_buf = skb;
1566 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001567 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1568 PCI_DMA_FROMDEVICE))
1569 return -1;
1570 }
1571
1572 skb_tmp = card->cmd_buf;
1573 if (skb_tmp) {
1574 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1575 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1576 PCI_DMA_FROMDEVICE);
1577 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001578 }
1579
1580 return 0;
1581}
1582
1583/*
1584 * This function handles firmware event ready interrupt
1585 */
1586static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1587{
1588 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001589 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001590 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1591 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001592 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001593 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001594
1595 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1596 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001597
1598 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001599 dev_dbg(adapter->dev, "info: Event being processed, "
1600 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001601 return 0;
1602 }
1603
1604 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1605 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1606 return -1;
1607 }
1608
1609 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001610 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001611 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001612 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001613 return -1;
1614 }
1615
1616 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001617 card->evtbd_rdptr, wrptr);
1618 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1619 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001620 ((wrptr & reg->evt_rollover_ind) ==
1621 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001622 struct sk_buff *skb_cmd;
1623 __le16 data_len = 0;
1624 u16 evt_len;
1625
1626 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1627 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001628 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1629 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1630 PCI_DMA_FROMDEVICE);
1631
Amitkumar Karward930fae2011-10-11 17:41:21 -07001632 /* Take the pointer and set it to event pointer in adapter
1633 and will return back after event handling callback */
1634 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001635 desc = card->evtbd_ring[rdptr];
1636 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001637
1638 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1639 adapter->event_cause = event;
1640 /* The first 4bytes will be the event transfer header
1641 len is 2 bytes followed by type which is 2 bytes */
1642 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1643 evt_len = le16_to_cpu(data_len);
1644
1645 skb_pull(skb_cmd, INTF_HEADER_LEN);
1646 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1647
1648 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1649 memcpy(adapter->event_body, skb_cmd->data +
1650 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1651 MWIFIEX_EVENT_HEADER_LEN);
1652
1653 adapter->event_received = true;
1654 adapter->event_skb = skb_cmd;
1655
1656 /* Do not update the event read pointer here, wait till the
1657 buffer is released. This is just to make things simpler,
1658 we need to find a better method of managing these buffers.
1659 */
1660 }
1661
1662 return 0;
1663}
1664
1665/*
1666 * Event processing complete handler
1667 */
1668static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1669 struct sk_buff *skb)
1670{
1671 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001672 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001673 int ret = 0;
1674 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1675 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001676 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001677 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001678
1679 if (!skb)
1680 return 0;
1681
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001682 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001683 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001684 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001685 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001686 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001687
1688 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001689 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001690 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001691 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001692 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001693 }
1694
1695 if (!card->evt_buf_list[rdptr]) {
1696 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001697 if (mwifiex_map_pci_memory(adapter, skb,
1698 MAX_EVENT_SIZE,
1699 PCI_DMA_FROMDEVICE))
1700 return -1;
1701 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001702 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001703 MWIFIEX_SKB_PACB(skb, &buf_pa);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001704 desc = card->evtbd_ring[rdptr];
1705 desc->paddr = buf_pa;
1706 desc->len = (u16)skb->len;
1707 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001708 skb = NULL;
1709 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001710 dev_dbg(adapter->dev,
1711 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1712 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001713 }
1714
1715 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1716 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001717 reg->evt_rollover_ind) ^
1718 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001719 }
1720
1721 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001722 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001723
Avinash Patildd04e6a2013-02-08 18:18:06 -08001724 /* Write the event ring read pointer in to reg->evt_rdptr */
1725 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1726 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001727 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001728 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001729 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001730 }
1731
Amitkumar Karward930fae2011-10-11 17:41:21 -07001732 dev_dbg(adapter->dev, "info: Check Events Again\n");
1733 ret = mwifiex_pcie_process_event_ready(adapter);
1734
1735 return ret;
1736}
1737
1738/*
1739 * This function downloads the firmware to the card.
1740 *
1741 * Firmware is downloaded to the card in blocks. Every block download
1742 * is tested for CRC errors, and retried a number of times before
1743 * returning failure.
1744 */
1745static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1746 struct mwifiex_fw_image *fw)
1747{
1748 int ret;
1749 u8 *firmware = fw->fw_buf;
1750 u32 firmware_len = fw->fw_len;
1751 u32 offset = 0;
1752 struct sk_buff *skb;
1753 u32 txlen, tx_blocks = 0, tries, len;
1754 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001755 dma_addr_t buf_pa;
1756 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001757 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001758
1759 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001760 dev_err(adapter->dev,
1761 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001762 return -1;
1763 }
1764
1765 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001766 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001767
1768 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001769 dev_err(adapter->dev,
1770 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001771 return -1;
1772 }
1773
1774 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1775 if (!skb) {
1776 ret = -ENOMEM;
1777 goto done;
1778 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001779
1780 /* Perform firmware data transfer */
1781 do {
1782 u32 ireg_intr = 0;
1783
1784 /* More data? */
1785 if (offset >= firmware_len)
1786 break;
1787
1788 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001789 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001790 &len);
1791 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001792 dev_warn(adapter->dev,
1793 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001794 goto done;
1795 }
1796 if (len)
1797 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001798 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001799 }
1800
1801 if (!len) {
1802 break;
1803 } else if (len > MWIFIEX_UPLD_SIZE) {
1804 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001805 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001806 ret = -1;
1807 goto done;
1808 }
1809
1810 txlen = len;
1811
1812 if (len & BIT(0)) {
1813 block_retry_cnt++;
1814 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1815 pr_err("FW download failure @ %d, over max "
1816 "retry count\n", offset);
1817 ret = -1;
1818 goto done;
1819 }
1820 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001821 "helper: len = 0x%04X, txlen = %d\n",
1822 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001823 len &= ~BIT(0);
1824 /* Setting this to 0 to resend from same offset */
1825 txlen = 0;
1826 } else {
1827 block_retry_cnt = 0;
1828 /* Set blocksize to transfer - checking for
1829 last block */
1830 if (firmware_len - offset < txlen)
1831 txlen = firmware_len - offset;
1832
1833 dev_dbg(adapter->dev, ".");
1834
Avinash Patildd04e6a2013-02-08 18:18:06 -08001835 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1836 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001837
1838 /* Copy payload to buffer */
1839 memmove(skb->data, &firmware[offset], txlen);
1840 }
1841
1842 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001843 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001844
1845 /* Send the boot command to device */
1846 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001847 dev_err(adapter->dev,
1848 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001849 ret = -1;
1850 goto done;
1851 }
Avinash Patilfc331462013-01-03 21:21:30 -08001852
1853 MWIFIEX_SKB_PACB(skb, &buf_pa);
1854
Amitkumar Karward930fae2011-10-11 17:41:21 -07001855 /* Wait for the command done interrupt */
1856 do {
1857 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1858 &ireg_intr)) {
1859 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001860 "interrupt status during fw dnld.\n",
1861 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001862 pci_unmap_single(card->dev, buf_pa, skb->len,
1863 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001864 ret = -1;
1865 goto done;
1866 }
1867 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1868 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001869
1870 pci_unmap_single(card->dev, buf_pa, skb->len,
1871 PCI_DMA_TODEVICE);
1872
Amitkumar Karward930fae2011-10-11 17:41:21 -07001873 offset += txlen;
1874 } while (true);
1875
1876 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001877 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001878
1879 ret = 0;
1880
1881done:
1882 dev_kfree_skb_any(skb);
1883 return ret;
1884}
1885
1886/*
1887 * This function checks the firmware status in card.
1888 *
1889 * The winner interface is also determined by this function.
1890 */
1891static int
1892mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1893{
1894 int ret = 0;
1895 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001896 struct pcie_service_card *card = adapter->card;
1897 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001898 u32 tries;
1899
1900 /* Mask spurios interrupts */
1901 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001902 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001903 dev_warn(adapter->dev, "Write register failed\n");
1904 return -1;
1905 }
1906
1907 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001908 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1909 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001910 dev_err(adapter->dev,
1911 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001912 return -1;
1913 }
1914
1915 /* Wait for firmware initialization event */
1916 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001917 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001918 &firmware_stat))
1919 ret = -1;
1920 else
1921 ret = 0;
1922 if (ret)
1923 continue;
1924 if (firmware_stat == FIRMWARE_READY_PCIE) {
1925 ret = 0;
1926 break;
1927 } else {
1928 mdelay(100);
1929 ret = -1;
1930 }
1931 }
1932
1933 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001934 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001935 &winner_status))
1936 ret = -1;
1937 else if (!winner_status) {
1938 dev_err(adapter->dev, "PCI-E is the winner\n");
1939 adapter->winner = 1;
1940 ret = -1;
1941 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001942 dev_err(adapter->dev,
1943 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1944 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001945 ret = 0;
1946 }
1947 }
1948
1949 return ret;
1950}
1951
1952/*
1953 * This function reads the interrupt status from card.
1954 */
1955static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1956{
1957 u32 pcie_ireg;
1958 unsigned long flags;
1959
1960 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1961 return;
1962
1963 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1964 dev_warn(adapter->dev, "Read register failed\n");
1965 return;
1966 }
1967
1968 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1969
1970 mwifiex_pcie_disable_host_int(adapter);
1971
1972 /* Clear the pending interrupts */
1973 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1974 ~pcie_ireg)) {
1975 dev_warn(adapter->dev, "Write register failed\n");
1976 return;
1977 }
1978 spin_lock_irqsave(&adapter->int_lock, flags);
1979 adapter->int_status |= pcie_ireg;
1980 spin_unlock_irqrestore(&adapter->int_lock, flags);
1981
1982 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1983 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1984 (adapter->ps_state == PS_STATE_SLEEP)) {
1985 mwifiex_pcie_enable_host_int(adapter);
1986 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001987 PCIE_CPU_INT_EVENT,
1988 CPU_INTR_SLEEP_CFM_DONE)
1989 ) {
1990 dev_warn(adapter->dev,
1991 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001992 return;
1993
1994 }
1995 }
1996 } else if (!adapter->pps_uapsd_mode &&
Avinash Patilc24d9922013-03-22 21:49:06 -07001997 adapter->ps_state == PS_STATE_SLEEP &&
1998 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001999 /* Potentially for PCIe we could get other
2000 * interrupts like shared. Don't change power
2001 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002002 adapter->ps_state = PS_STATE_AWAKE;
2003 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002004 }
2005 }
2006}
2007
2008/*
2009 * Interrupt handler for PCIe root port
2010 *
2011 * This function reads the interrupt status from firmware and assigns
2012 * the main process in workqueue which will handle the interrupt.
2013 */
2014static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2015{
2016 struct pci_dev *pdev = (struct pci_dev *)context;
2017 struct pcie_service_card *card;
2018 struct mwifiex_adapter *adapter;
2019
2020 if (!pdev) {
2021 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2022 goto exit;
2023 }
2024
2025 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
2026 if (!card || !card->adapter) {
2027 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002028 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002029 goto exit;
2030 }
2031 adapter = card->adapter;
2032
2033 if (adapter->surprise_removed)
2034 goto exit;
2035
2036 mwifiex_interrupt_status(adapter);
2037 queue_work(adapter->workqueue, &adapter->main_work);
2038
2039exit:
2040 return IRQ_HANDLED;
2041}
2042
2043/*
2044 * This function checks the current interrupt status.
2045 *
2046 * The following interrupts are checked and handled by this function -
2047 * - Data sent
2048 * - Command sent
2049 * - Command received
2050 * - Packets received
2051 * - Events received
2052 *
2053 * In case of Rx packets received, the packets are uploaded from card to
2054 * host and processed accordingly.
2055 */
2056static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2057{
2058 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002059 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002060 unsigned long flags;
2061
2062 spin_lock_irqsave(&adapter->int_lock, flags);
2063 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002064 pcie_ireg = adapter->int_status;
2065 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002066 spin_unlock_irqrestore(&adapter->int_lock, flags);
2067
Avinash Patil659c4782013-01-03 21:21:28 -08002068 while (pcie_ireg & HOST_INTR_MASK) {
2069 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2070 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002071 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2072 ret = mwifiex_pcie_send_data_complete(adapter);
2073 if (ret)
2074 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002075 }
Avinash Patil659c4782013-01-03 21:21:28 -08002076 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2077 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002078 dev_dbg(adapter->dev, "info: Rx DATA\n");
2079 ret = mwifiex_pcie_process_recv_data(adapter);
2080 if (ret)
2081 return ret;
2082 }
Avinash Patil659c4782013-01-03 21:21:28 -08002083 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2084 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002085 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2086 ret = mwifiex_pcie_process_event_ready(adapter);
2087 if (ret)
2088 return ret;
2089 }
2090
Avinash Patil659c4782013-01-03 21:21:28 -08002091 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2092 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002093 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002094 dev_dbg(adapter->dev,
2095 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002096 adapter->cmd_sent = false;
2097 }
2098 /* Handle command response */
2099 ret = mwifiex_pcie_process_cmd_complete(adapter);
2100 if (ret)
2101 return ret;
2102 }
2103
2104 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2105 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2106 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002107 dev_warn(adapter->dev,
2108 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002109 return -1;
2110 }
2111
2112 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2113 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002114 PCIE_HOST_INT_STATUS,
2115 ~pcie_ireg)) {
2116 dev_warn(adapter->dev,
2117 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002118 return -1;
2119 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002120 }
2121
2122 }
2123 }
2124 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002125 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002126 if (adapter->ps_state != PS_STATE_SLEEP)
2127 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002128
2129 return 0;
2130}
2131
2132/*
2133 * This function downloads data from driver to card.
2134 *
2135 * Both commands and data packets are transferred to the card by this
2136 * function.
2137 *
2138 * This function adds the PCIE specific header to the front of the buffer
2139 * before transferring. The header contains the length of the packet and
2140 * the type. The firmware handles the packets based upon this set type.
2141 */
2142static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2143 struct sk_buff *skb,
2144 struct mwifiex_tx_param *tx_param)
2145{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002146 if (!skb) {
2147 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002148 return -1;
2149 }
2150
2151 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002152 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002153 else if (type == MWIFIEX_TYPE_CMD)
2154 return mwifiex_pcie_send_cmd(adapter, skb);
2155
2156 return 0;
2157}
2158
2159/*
2160 * This function initializes the PCI-E host memory space, WCB rings, etc.
2161 *
2162 * The following initializations steps are followed -
2163 * - Allocate TXBD ring buffers
2164 * - Allocate RXBD ring buffers
2165 * - Allocate event BD ring buffers
2166 * - Allocate command response ring buffer
2167 * - Allocate sleep cookie buffer
2168 */
2169static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2170{
2171 struct pcie_service_card *card = adapter->card;
2172 int ret;
2173 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002174 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002175
2176 pci_set_drvdata(pdev, card);
2177
2178 ret = pci_enable_device(pdev);
2179 if (ret)
2180 goto err_enable_dev;
2181
2182 pci_set_master(pdev);
2183
2184 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2185 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2186 if (ret) {
2187 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2188 goto err_set_dma_mask;
2189 }
2190
2191 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2192 if (ret) {
2193 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2194 goto err_set_dma_mask;
2195 }
2196
2197 ret = pci_request_region(pdev, 0, DRV_NAME);
2198 if (ret) {
2199 dev_err(adapter->dev, "req_reg(0) error\n");
2200 goto err_req_region0;
2201 }
2202 card->pci_mmap = pci_iomap(pdev, 0, 0);
2203 if (!card->pci_mmap) {
2204 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002205 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002206 goto err_iomap0;
2207 }
2208 ret = pci_request_region(pdev, 2, DRV_NAME);
2209 if (ret) {
2210 dev_err(adapter->dev, "req_reg(2) error\n");
2211 goto err_req_region2;
2212 }
2213 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2214 if (!card->pci_mmap1) {
2215 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002216 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002217 goto err_iomap2;
2218 }
2219
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002220 dev_dbg(adapter->dev,
2221 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2222 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002223
2224 card->cmdrsp_buf = NULL;
2225 ret = mwifiex_pcie_create_txbd_ring(adapter);
2226 if (ret)
2227 goto err_cre_txbd;
2228 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2229 if (ret)
2230 goto err_cre_rxbd;
2231 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2232 if (ret)
2233 goto err_cre_evtbd;
2234 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2235 if (ret)
2236 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002237 if (reg->sleep_cookie) {
2238 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2239 if (ret)
2240 goto err_alloc_cookie;
2241 } else {
2242 card->sleep_cookie_vbase = NULL;
2243 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002244 return ret;
2245
2246err_alloc_cookie:
2247 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2248err_alloc_cmdbuf:
2249 mwifiex_pcie_delete_evtbd_ring(adapter);
2250err_cre_evtbd:
2251 mwifiex_pcie_delete_rxbd_ring(adapter);
2252err_cre_rxbd:
2253 mwifiex_pcie_delete_txbd_ring(adapter);
2254err_cre_txbd:
2255 pci_iounmap(pdev, card->pci_mmap1);
2256err_iomap2:
2257 pci_release_region(pdev, 2);
2258err_req_region2:
2259 pci_iounmap(pdev, card->pci_mmap);
2260err_iomap0:
2261 pci_release_region(pdev, 0);
2262err_req_region0:
2263err_set_dma_mask:
2264 pci_disable_device(pdev);
2265err_enable_dev:
2266 pci_set_drvdata(pdev, NULL);
2267 return ret;
2268}
2269
2270/*
2271 * This function cleans up the allocated card buffers.
2272 *
2273 * The following are freed by this function -
2274 * - TXBD ring buffers
2275 * - RXBD ring buffers
2276 * - Event BD ring buffers
2277 * - Command response ring buffer
2278 * - Sleep cookie buffer
2279 */
2280static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2281{
2282 struct pcie_service_card *card = adapter->card;
2283 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002284 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002285
Amitkumar Karward930fae2011-10-11 17:41:21 -07002286 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002287 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002288 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002289 dev_err(adapter->dev,
2290 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002291 }
2292
2293 if (pdev) {
2294 pci_iounmap(pdev, card->pci_mmap);
2295 pci_iounmap(pdev, card->pci_mmap1);
2296
2297 pci_release_regions(pdev);
2298 pci_disable_device(pdev);
2299 pci_set_drvdata(pdev, NULL);
2300 }
2301}
2302
2303/*
2304 * This function registers the PCIE device.
2305 *
2306 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2307 */
2308static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2309{
2310 int ret;
2311 struct pcie_service_card *card = adapter->card;
2312 struct pci_dev *pdev = card->dev;
2313
2314 /* save adapter pointer in card */
2315 card->adapter = adapter;
2316
2317 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2318 "MRVL_PCIE", pdev);
2319 if (ret) {
2320 pr_err("request_irq failed: ret=%d\n", ret);
2321 adapter->card = NULL;
2322 return -1;
2323 }
2324
2325 adapter->dev = &pdev->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002326 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002327
2328 return 0;
2329}
2330
2331/*
2332 * This function unregisters the PCIE device.
2333 *
2334 * The PCIE IRQ is released, the function is disabled and driver
2335 * data is set to null.
2336 */
2337static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2338{
2339 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002340 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002341
2342 if (card) {
2343 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2344 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002345
Avinash Patil52301a82013-02-12 14:38:32 -08002346 reg = card->pcie.reg;
2347 if (reg->sleep_cookie)
2348 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2349
Avinash Patilfc331462013-01-03 21:21:30 -08002350 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2351 mwifiex_pcie_delete_evtbd_ring(adapter);
2352 mwifiex_pcie_delete_rxbd_ring(adapter);
2353 mwifiex_pcie_delete_txbd_ring(adapter);
2354 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002355 }
2356}
2357
2358static struct mwifiex_if_ops pcie_ops = {
2359 .init_if = mwifiex_pcie_init,
2360 .cleanup_if = mwifiex_pcie_cleanup,
2361 .check_fw_status = mwifiex_check_fw_status,
2362 .prog_fw = mwifiex_prog_fw_w_helper,
2363 .register_dev = mwifiex_register_dev,
2364 .unregister_dev = mwifiex_unregister_dev,
2365 .enable_int = mwifiex_pcie_enable_host_int,
2366 .process_int_status = mwifiex_process_int_status,
2367 .host_to_card = mwifiex_pcie_host_to_card,
2368 .wakeup = mwifiex_pm_wakeup_card,
2369 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2370
2371 /* PCIE specific */
2372 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2373 .event_complete = mwifiex_pcie_event_complete,
2374 .update_mp_end_port = NULL,
2375 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002376 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002377 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002378};
2379
2380/*
2381 * This function initializes the PCIE driver module.
2382 *
2383 * This initiates the semaphore and registers the device with
2384 * PCIE bus.
2385 */
2386static int mwifiex_pcie_init_module(void)
2387{
2388 int ret;
2389
Avinash Patilca8f2112013-02-08 18:18:09 -08002390 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002391
2392 sema_init(&add_remove_card_sem, 1);
2393
2394 /* Clear the flag in case user removes the card. */
2395 user_rmmod = 0;
2396
2397 ret = pci_register_driver(&mwifiex_pcie);
2398 if (ret)
2399 pr_err("Driver register failed!\n");
2400 else
2401 pr_debug("info: Driver registered successfully!\n");
2402
2403 return ret;
2404}
2405
2406/*
2407 * This function cleans up the PCIE driver.
2408 *
2409 * The following major steps are followed for cleanup -
2410 * - Resume the device if its suspended
2411 * - Disconnect the device if connected
2412 * - Shutdown the firmware
2413 * - Unregister the device from PCIE bus.
2414 */
2415static void mwifiex_pcie_cleanup_module(void)
2416{
2417 if (!down_interruptible(&add_remove_card_sem))
2418 up(&add_remove_card_sem);
2419
2420 /* Set the flag as user is removing this module. */
2421 user_rmmod = 1;
2422
2423 pci_unregister_driver(&mwifiex_pcie);
2424}
2425
2426module_init(mwifiex_pcie_init_module);
2427module_exit(mwifiex_pcie_cleanup_module);
2428
2429MODULE_AUTHOR("Marvell International Ltd.");
2430MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2431MODULE_VERSION(PCIE_VERSION);
2432MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002433MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2434MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);