blob: df88e65595c8a2bd9d6658a388ff3d77d447d335 [file] [log] [blame]
Amitkumar Karward930fae2011-10-11 17:41:21 -07001/*
2 * Marvell Wireless LAN device driver: PCIE specific handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/firmware.h>
21
22#include "decl.h"
23#include "ioctl.h"
24#include "util.h"
25#include "fw.h"
26#include "main.h"
27#include "wmm.h"
28#include "11n.h"
29#include "pcie.h"
30
31#define PCIE_VERSION "1.0"
32#define DRV_NAME "Marvell mwifiex PCIe"
33
34static u8 user_rmmod;
35
36static struct mwifiex_if_ops pcie_ops;
37
38static struct semaphore add_remove_card_sem;
39static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
40static int mwifiex_pcie_resume(struct pci_dev *pdev);
41
Avinash Patilfc331462013-01-03 21:21:30 -080042static int
43mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
44 int size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070045{
Avinash Patilfc331462013-01-03 21:21:30 -080046 struct pcie_service_card *card = adapter->card;
47 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -070048
Avinash Patilfc331462013-01-03 21:21:30 -080049 buf_pa = pci_map_single(card->dev, skb->data, size, flags);
50 if (pci_dma_mapping_error(card->dev, buf_pa)) {
51 dev_err(adapter->dev, "failed to map pci memory!\n");
52 return -1;
53 }
54 memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t));
55 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070056}
57
58/*
59 * This function reads sleep cookie and checks if FW is ready
60 */
61static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
62{
63 u32 *cookie_addr;
64 struct pcie_service_card *card = adapter->card;
65
Avinash Patilfc331462013-01-03 21:21:30 -080066 if (card->sleep_cookie_vbase) {
67 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070068 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
69 *cookie_addr);
70 if (*cookie_addr == FW_AWAKE_COOKIE)
71 return true;
72 }
73
74 return false;
75}
76
77/*
78 * This function probes an mwifiex device and registers it. It allocates
79 * the card structure, enables PCIE function number and initiates the
80 * device registration and initialization procedure by adding a logical
81 * interface.
82 */
83static int mwifiex_pcie_probe(struct pci_dev *pdev,
84 const struct pci_device_id *ent)
85{
86 struct pcie_service_card *card;
87
88 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -070089 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -070090
91 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +000092 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -070093 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -070094
95 card->dev = pdev;
96
97 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
98 MWIFIEX_PCIE)) {
99 pr_err("%s failed\n", __func__);
100 kfree(card);
101 return -1;
102 }
103
104 return 0;
105}
106
107/*
108 * This function removes the interface and frees up the card structure.
109 */
110static void mwifiex_pcie_remove(struct pci_dev *pdev)
111{
112 struct pcie_service_card *card;
113 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700114 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700115 int i;
116
117 card = pci_get_drvdata(pdev);
118 if (!card)
119 return;
120
121 adapter = card->adapter;
122 if (!adapter || !adapter->priv_num)
123 return;
124
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700125 /* In case driver is removed when asynchronous FW load is in progress */
126 wait_for_completion(&adapter->fw_load);
127
Amitkumar Karward930fae2011-10-11 17:41:21 -0700128 if (user_rmmod) {
129#ifdef CONFIG_PM
130 if (adapter->is_suspended)
131 mwifiex_pcie_resume(pdev);
132#endif
133
134 for (i = 0; i < adapter->priv_num; i++)
135 if ((GET_BSS_ROLE(adapter->priv[i]) ==
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700136 MWIFIEX_BSS_ROLE_STA) &&
137 adapter->priv[i]->media_connected)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700138 mwifiex_deauthenticate(adapter->priv[i], NULL);
139
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700140 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700141
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700142 mwifiex_disable_auto_ds(priv);
143
144 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700145 }
146
147 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
148 kfree(card);
149}
150
151/*
152 * Kernel needs to suspend all functions separately. Therefore all
153 * registered functions must have drivers with suspend and resume
154 * methods. Failing that the kernel simply removes the whole card.
155 *
156 * If already not suspended, this function allocates and sends a host
157 * sleep activate request to the firmware and turns off the traffic.
158 */
159static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
160{
161 struct mwifiex_adapter *adapter;
162 struct pcie_service_card *card;
163 int hs_actived, i;
164
165 if (pdev) {
166 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
Avinash Patil83f0c6d2013-01-21 21:04:10 -0800167 if (!card || !card->adapter) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700168 pr_err("Card or adapter structure is not valid\n");
169 return 0;
170 }
171 } else {
172 pr_err("PCIE device is not specified\n");
173 return 0;
174 }
175
176 adapter = card->adapter;
177
178 hs_actived = mwifiex_enable_hs(adapter);
179
180 /* Indicate device suspended */
181 adapter->is_suspended = true;
182
183 for (i = 0; i < adapter->priv_num; i++)
184 netif_carrier_off(adapter->priv[i]->netdev);
185
186 return 0;
187}
188
189/*
190 * Kernel needs to suspend all functions separately. Therefore all
191 * registered functions must have drivers with suspend and resume
192 * methods. Failing that the kernel simply removes the whole card.
193 *
194 * If already not resumed, this function turns on the traffic and
195 * sends a host sleep cancel request to the firmware.
196 */
197static int mwifiex_pcie_resume(struct pci_dev *pdev)
198{
199 struct mwifiex_adapter *adapter;
200 struct pcie_service_card *card;
201 int i;
202
203 if (pdev) {
204 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
205 if (!card || !card->adapter) {
206 pr_err("Card or adapter structure is not valid\n");
207 return 0;
208 }
209 } else {
210 pr_err("PCIE device is not specified\n");
211 return 0;
212 }
213
214 adapter = card->adapter;
215
216 if (!adapter->is_suspended) {
217 dev_warn(adapter->dev, "Device already resumed\n");
218 return 0;
219 }
220
221 adapter->is_suspended = false;
222
223 for (i = 0; i < adapter->priv_num; i++)
224 if (adapter->priv[i]->media_connected)
225 netif_carrier_on(adapter->priv[i]->netdev);
226
227 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700228 MWIFIEX_ASYNC_CMD);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700229
230 return 0;
231}
232
233#define PCIE_VENDOR_ID_MARVELL (0x11ab)
234#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30)
235
236static 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,
240 },
241 {},
242};
243
244MODULE_DEVICE_TABLE(pci, mwifiex_ids);
245
246/* PCI Device Driver */
247static struct pci_driver __refdata mwifiex_pcie = {
248 .name = "mwifiex_pcie",
249 .id_table = mwifiex_ids,
250 .probe = mwifiex_pcie_probe,
251 .remove = mwifiex_pcie_remove,
252#ifdef CONFIG_PM
253 /* Power Management Hooks */
254 .suspend = mwifiex_pcie_suspend,
255 .resume = mwifiex_pcie_resume,
256#endif
257};
258
259/*
260 * This function writes data into PCIE card register.
261 */
262static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
263{
264 struct pcie_service_card *card = adapter->card;
265
266 iowrite32(data, card->pci_mmap1 + reg);
267
268 return 0;
269}
270
271/*
272 * This function reads data from PCIE card register.
273 */
274static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
275{
276 struct pcie_service_card *card = adapter->card;
277
278 *data = ioread32(card->pci_mmap1 + reg);
279
280 return 0;
281}
282
283/*
284 * This function wakes up the card.
285 *
286 * A host power up command is written to the card configuration
287 * register to wake up the card.
288 */
289static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
290{
291 int i = 0;
292
293 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
294 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700295 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700296 /* 50ms max wait */
297 if (i == 50000)
298 break;
299 }
300
301 dev_dbg(adapter->dev, "event: Wakeup device...\n");
302
303 /* Enable interrupts or any chip access will wakeup device */
304 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) {
305 dev_warn(adapter->dev, "Enable host interrupt failed\n");
306 return -1;
307 }
308
309 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
310 adapter->ps_state = PS_STATE_AWAKE;
311
312 return 0;
313}
314
315/*
316 * This function is called after the card has woken up.
317 *
318 * The card configuration register is reset.
319 */
320static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
321{
322 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
323
324 return 0;
325}
326
327/*
328 * This function disables the host interrupt.
329 *
330 * The host interrupt mask is read, the disable bit is reset and
331 * written back to the card host interrupt mask register.
332 */
333static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
334{
335 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
336 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
337 0x00000000)) {
338 dev_warn(adapter->dev, "Disable host interrupt failed\n");
339 return -1;
340 }
341 }
342
343 return 0;
344}
345
346/*
347 * This function enables the host interrupt.
348 *
349 * The host interrupt enable mask is written to the card
350 * host interrupt mask register.
351 */
352static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
353{
354 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
355 /* Simply write the mask to the register */
356 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
357 HOST_INTR_MASK)) {
358 dev_warn(adapter->dev, "Enable host interrupt failed\n");
359 return -1;
360 }
361 }
362
363 return 0;
364}
365
366/*
367 * This function creates buffer descriptor ring for TX
368 */
369static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
370{
371 struct pcie_service_card *card = adapter->card;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700372 int i;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700373
374 /*
375 * driver maintaines the write pointer and firmware maintaines the read
376 * pointer. The write pointer starts at 0 (zero) while the read pointer
377 * starts at zero with rollover bit set
378 */
379 card->txbd_wrptr = 0;
380 card->txbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
381
382 /* allocate shared memory for the BD ring and divide the same in to
383 several descriptors */
384 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700385 MWIFIEX_MAX_TXRX_BD;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700386 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700387 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800388 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
389 card->txbd_ring_size,
390 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700391 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800392 dev_err(adapter->dev,
393 "allocate consistent memory (%d bytes) failed!\n",
394 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800395 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700396 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700397 dev_dbg(adapter->dev,
398 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800399 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700400 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700401
402 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
403 card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700404 (card->txbd_ring_vbase +
405 (sizeof(struct mwifiex_pcie_buf_desc)
406 * i));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700407
Avinash Patilfc331462013-01-03 21:21:30 -0800408 card->tx_buf_list[i] = NULL;
409 card->txbd_ring[i]->paddr = 0;
410 card->txbd_ring[i]->len = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700411 card->txbd_ring[i]->flags = 0;
412 }
413
414 return 0;
415}
416
417static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
418{
419 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -0800420 struct sk_buff *skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700421 int i;
422
423 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilfc331462013-01-03 21:21:30 -0800424 if (card->tx_buf_list[i]) {
425 skb = card->tx_buf_list[i];
426 pci_unmap_single(card->dev, card->txbd_ring[i]->paddr,
427 skb->len, PCI_DMA_TODEVICE);
428 dev_kfree_skb_any(skb);
429 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700430 card->tx_buf_list[i] = NULL;
431 card->txbd_ring[i]->paddr = 0;
432 card->txbd_ring[i]->len = 0;
433 card->txbd_ring[i]->flags = 0;
434 card->txbd_ring[i] = NULL;
435 }
436
Avinash Patilfc331462013-01-03 21:21:30 -0800437 if (card->txbd_ring_vbase)
438 pci_free_consistent(card->dev, card->txbd_ring_size,
439 card->txbd_ring_vbase,
440 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700441 card->txbd_ring_size = 0;
442 card->txbd_wrptr = 0;
443 card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
444 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800445 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700446
447 return 0;
448}
449
450/*
451 * This function creates buffer descriptor ring for RX
452 */
453static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
454{
455 struct pcie_service_card *card = adapter->card;
456 struct sk_buff *skb;
457 int i;
Avinash Patilfc331462013-01-03 21:21:30 -0800458 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700459
460 /*
461 * driver maintaines the read pointer and firmware maintaines the write
462 * pointer. The write pointer starts at 0 (zero) while the read pointer
463 * starts at zero with rollover bit set
464 */
465 card->rxbd_wrptr = 0;
466 card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
467
468 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700469 MWIFIEX_MAX_TXRX_BD;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700470 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700471 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800472 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
473 card->rxbd_ring_size,
474 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700475 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800476 dev_err(adapter->dev,
477 "allocate consistent memory (%d bytes) failed!\n",
478 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800479 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700480 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700481
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700482 dev_dbg(adapter->dev,
483 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
484 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
485 (u32)((u64)card->rxbd_ring_pbase >> 32),
486 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700487
488 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
489 card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700490 (card->rxbd_ring_vbase +
491 (sizeof(struct mwifiex_pcie_buf_desc)
492 * i));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700493
494 /* Allocate skb here so that firmware can DMA data from it */
495 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
496 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700497 dev_err(adapter->dev,
498 "Unable to allocate skb for RX ring.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700499 kfree(card->rxbd_ring_vbase);
500 return -ENOMEM;
501 }
Avinash Patilfc331462013-01-03 21:21:30 -0800502 if (mwifiex_map_pci_memory(adapter, skb,
503 MWIFIEX_RX_DATA_BUF_SIZE,
504 PCI_DMA_FROMDEVICE))
505 return -1;
506
507 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700508
509 dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700510 "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800511 skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32),
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700512 skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700513
514 card->rx_buf_list[i] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -0800515 card->rxbd_ring[i]->paddr = buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700516 card->rxbd_ring[i]->len = (u16)skb->len;
517 card->rxbd_ring[i]->flags = 0;
518 }
519
520 return 0;
521}
522
523/*
524 * This function deletes Buffer descriptor ring for RX
525 */
526static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
527{
528 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -0800529 struct sk_buff *skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700530 int i;
531
532 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilfc331462013-01-03 21:21:30 -0800533 if (card->rx_buf_list[i]) {
534 skb = card->rx_buf_list[i];
535 pci_unmap_single(card->dev, card->rxbd_ring[i]->paddr ,
536 MWIFIEX_RX_DATA_BUF_SIZE,
537 PCI_DMA_FROMDEVICE);
538 dev_kfree_skb_any(skb);
539 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700540 card->rx_buf_list[i] = NULL;
541 card->rxbd_ring[i]->paddr = 0;
542 card->rxbd_ring[i]->len = 0;
543 card->rxbd_ring[i]->flags = 0;
544 card->rxbd_ring[i] = NULL;
545 }
546
Avinash Patilfc331462013-01-03 21:21:30 -0800547 if (card->rxbd_ring_vbase)
548 pci_free_consistent(card->dev, card->rxbd_ring_size,
549 card->rxbd_ring_vbase,
550 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700551 card->rxbd_ring_size = 0;
552 card->rxbd_wrptr = 0;
553 card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
554 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800555 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700556
557 return 0;
558}
559
560/*
561 * This function creates buffer descriptor ring for Events
562 */
563static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
564{
565 struct pcie_service_card *card = adapter->card;
566 struct sk_buff *skb;
567 int i;
Avinash Patilfc331462013-01-03 21:21:30 -0800568 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700569
570 /*
571 * driver maintaines the read pointer and firmware maintaines the write
572 * pointer. The write pointer starts at 0 (zero) while the read pointer
573 * starts at zero with rollover bit set
574 */
575 card->evtbd_wrptr = 0;
576 card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
577
578 card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700579 MWIFIEX_MAX_EVT_BD;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700580 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700581 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800582 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
583 card->evtbd_ring_size,
584 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700585 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700586 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800587 "allocate consistent memory (%d bytes) failed!\n",
588 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800589 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700590 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700591
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700592 dev_dbg(adapter->dev,
593 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
594 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
595 (u32)((u64)card->evtbd_ring_pbase >> 32),
596 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700597
598 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
599 card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700600 (card->evtbd_ring_vbase +
601 (sizeof(struct mwifiex_pcie_buf_desc)
602 * i));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700603
604 /* Allocate skb here so that firmware can DMA data from it */
605 skb = dev_alloc_skb(MAX_EVENT_SIZE);
606 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700607 dev_err(adapter->dev,
608 "Unable to allocate skb for EVENT buf.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700609 kfree(card->evtbd_ring_vbase);
610 return -ENOMEM;
611 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700612 skb_put(skb, MAX_EVENT_SIZE);
613
Avinash Patilfc331462013-01-03 21:21:30 -0800614 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
615 PCI_DMA_FROMDEVICE))
616 return -1;
617
618 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700619 dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700620 "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800621 skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32),
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700622 skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700623
624 card->evt_buf_list[i] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -0800625 card->evtbd_ring[i]->paddr = buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700626 card->evtbd_ring[i]->len = (u16)skb->len;
627 card->evtbd_ring[i]->flags = 0;
628 }
629
630 return 0;
631}
632
633/*
634 * This function deletes Buffer descriptor ring for Events
635 */
636static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
637{
638 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -0800639 struct sk_buff *skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700640 int i;
641
642 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
Avinash Patilfc331462013-01-03 21:21:30 -0800643 if (card->evt_buf_list[i]) {
644 skb = card->evt_buf_list[i];
645 pci_unmap_single(card->dev, card->evtbd_ring[i]->paddr,
646 MAX_EVENT_SIZE, PCI_DMA_FROMDEVICE);
647 dev_kfree_skb_any(skb);
648 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700649 card->evt_buf_list[i] = NULL;
650 card->evtbd_ring[i]->paddr = 0;
651 card->evtbd_ring[i]->len = 0;
652 card->evtbd_ring[i]->flags = 0;
653 card->evtbd_ring[i] = NULL;
654 }
655
Avinash Patilfc331462013-01-03 21:21:30 -0800656 if (card->evtbd_ring_vbase)
657 pci_free_consistent(card->dev, card->evtbd_ring_size,
658 card->evtbd_ring_vbase,
659 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700660 card->evtbd_wrptr = 0;
661 card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
662 card->evtbd_ring_size = 0;
663 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800664 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700665
666 return 0;
667}
668
669/*
670 * This function allocates a buffer for CMDRSP
671 */
672static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
673{
674 struct pcie_service_card *card = adapter->card;
675 struct sk_buff *skb;
676
677 /* Allocate memory for receiving command response data */
678 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
679 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700680 dev_err(adapter->dev,
681 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700682 return -ENOMEM;
683 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700684 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800685 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
686 PCI_DMA_FROMDEVICE))
687 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700688
Avinash Patilfc331462013-01-03 21:21:30 -0800689 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700690
691 return 0;
692}
693
694/*
695 * This function deletes a buffer for CMDRSP
696 */
697static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
698{
699 struct pcie_service_card *card;
Avinash Patilfc331462013-01-03 21:21:30 -0800700 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700701
702 if (!adapter)
703 return 0;
704
705 card = adapter->card;
706
Avinash Patilfc331462013-01-03 21:21:30 -0800707 if (card && card->cmdrsp_buf) {
708 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
709 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
710 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700711 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800712 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700713
Avinash Patilfc331462013-01-03 21:21:30 -0800714 if (card && card->cmd_buf) {
715 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
716 pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER,
717 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700718 dev_kfree_skb_any(card->cmd_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800719 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700720 return 0;
721}
722
723/*
724 * This function allocates a buffer for sleep cookie
725 */
726static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
727{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700728 struct pcie_service_card *card = adapter->card;
729
Avinash Patilfc331462013-01-03 21:21:30 -0800730 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
731 &card->sleep_cookie_pbase);
732 if (!card->sleep_cookie_vbase) {
733 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700734 return -ENOMEM;
735 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700736 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800737 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700738
739 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800740 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700741
742 return 0;
743}
744
745/*
746 * This function deletes buffer for sleep cookie
747 */
748static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
749{
750 struct pcie_service_card *card;
751
752 if (!adapter)
753 return 0;
754
755 card = adapter->card;
756
Avinash Patilfc331462013-01-03 21:21:30 -0800757 if (card && card->sleep_cookie_vbase) {
758 pci_free_consistent(card->dev, sizeof(u32),
759 card->sleep_cookie_vbase,
760 card->sleep_cookie_pbase);
761 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700762 }
763
764 return 0;
765}
766
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800767/* This function flushes the TX buffer descriptor ring
768 * This function defined as handler is also called while cleaning TXRX
769 * during disconnect/ bss stop.
770 */
771static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
772{
773 struct pcie_service_card *card = adapter->card;
774 u32 rdptr;
775
776 /* Read the TX ring read pointer set by firmware */
777 if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
778 dev_err(adapter->dev,
779 "Flush TXBD: failed to read REG_TXBD_RDPTR\n");
780 return -1;
781 }
782
783 if (!mwifiex_pcie_txbd_empty(card, rdptr)) {
784 card->txbd_flush = 1;
785 /* write pointer already set at last send
786 * send dnld-rdy intr again, wait for completion.
787 */
788 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
789 CPU_INTR_DNLD_RDY)) {
790 dev_err(adapter->dev,
791 "failed to assert dnld-rdy interrupt.\n");
792 return -1;
793 }
794 }
795 return 0;
796}
797
Amitkumar Karward930fae2011-10-11 17:41:21 -0700798/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800799 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700800 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800801static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700802{
Avinash Patile7f767a2013-01-03 21:21:32 -0800803 const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD;
804 struct sk_buff *skb;
805 dma_addr_t buf_pa;
806 u32 wrdoneidx, rdptr, unmap_count = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700807 struct pcie_service_card *card = adapter->card;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700808
809 if (!mwifiex_pcie_ok_to_access_hw(adapter))
810 mwifiex_pm_wakeup_card(adapter);
811
812 /* Read the TX ring read pointer set by firmware */
813 if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700814 dev_err(adapter->dev,
Avinash Patile7f767a2013-01-03 21:21:32 -0800815 "SEND COMP: failed to read REG_TXBD_RDPTR\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700816 return -1;
817 }
818
Avinash Patile7f767a2013-01-03 21:21:32 -0800819 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
820 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700821
Avinash Patile7f767a2013-01-03 21:21:32 -0800822 /* free from previous txbd_rdptr to current txbd_rdptr */
823 while (((card->txbd_rdptr & MWIFIEX_TXBD_MASK) !=
824 (rdptr & MWIFIEX_TXBD_MASK)) ||
825 ((card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
826 (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
827 wrdoneidx = card->txbd_rdptr & MWIFIEX_TXBD_MASK;
828
829 skb = card->tx_buf_list[wrdoneidx];
830 if (skb) {
831 dev_dbg(adapter->dev,
832 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
833 skb, wrdoneidx);
834 MWIFIEX_SKB_PACB(skb, &buf_pa);
835 pci_unmap_single(card->dev, buf_pa, skb->len,
836 PCI_DMA_TODEVICE);
837
838 unmap_count++;
839
840 if (card->txbd_flush)
841 mwifiex_write_data_complete(adapter, skb, 0,
842 -1);
843 else
844 mwifiex_write_data_complete(adapter, skb, 0, 0);
845 }
846
847 card->tx_buf_list[wrdoneidx] = NULL;
848 card->txbd_ring[wrdoneidx]->paddr = 0;
Avinash Patil6ccea752013-01-22 16:29:03 -0800849 card->txbd_ring[wrdoneidx]->len = 0;
850 card->txbd_ring[wrdoneidx]->flags = 0;
Avinash Patile7f767a2013-01-03 21:21:32 -0800851 card->txbd_rdptr++;
852
853 if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs)
854 card->txbd_rdptr = ((card->txbd_rdptr &
855 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
856 MWIFIEX_BD_FLAG_ROLLOVER_IND);
857 }
858
859 if (unmap_count)
860 adapter->data_sent = false;
861
862 if (card->txbd_flush) {
863 if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
864 (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) &&
865 ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
866 (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND)))
867 card->txbd_flush = 0;
868 else
869 mwifiex_clean_pcie_ring_buf(adapter);
870 }
871
872 return 0;
873}
874
875/* This function sends data buffer to device. First 4 bytes of payload
876 * are filled with payload length and payload type. Then this payload
877 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
878 * Download ready interrupt to FW is deffered if Tx ring is not full and
879 * additional payload can be accomodated.
880 */
881static int
882mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
883 struct mwifiex_tx_param *tx_param)
884{
885 struct pcie_service_card *card = adapter->card;
886 u32 wrindx;
887 int ret;
888 dma_addr_t buf_pa;
889 __le16 *tmp;
890
891 if (!(skb->data && skb->len)) {
892 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
893 __func__, skb->data, skb->len);
894 return -1;
895 }
896
897 if (!mwifiex_pcie_ok_to_access_hw(adapter))
898 mwifiex_pm_wakeup_card(adapter);
899
900 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
901 card->txbd_rdptr, card->txbd_wrptr);
902 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700903 u8 *payload;
904
905 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -0800906 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700907 tmp = (__le16 *)&payload[0];
908 *tmp = cpu_to_le16((u16)skb->len);
909 tmp = (__le16 *)&payload[2];
910 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -0800911
912 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
913 PCI_DMA_TODEVICE))
914 return -1;
915
916 wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;
917 MWIFIEX_SKB_PACB(skb, &buf_pa);
918 card->tx_buf_list[wrindx] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -0800919 card->txbd_ring[wrindx]->paddr = buf_pa;
Avinash Patile7f767a2013-01-03 21:21:32 -0800920 card->txbd_ring[wrindx]->len = (u16)skb->len;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700921 card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
922 MWIFIEX_BD_FLAG_LAST_DESC;
923
924 if ((++card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
925 MWIFIEX_MAX_TXRX_BD)
926 card->txbd_wrptr = ((card->txbd_wrptr &
927 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
928 MWIFIEX_BD_FLAG_ROLLOVER_IND);
929
930 /* Write the TX ring write pointer in to REG_TXBD_WRPTR */
931 if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700932 card->txbd_wrptr)) {
933 dev_err(adapter->dev,
934 "SEND DATA: failed to write REG_TXBD_WRPTR\n");
Avinash Patile7f767a2013-01-03 21:21:32 -0800935 ret = -1;
936 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700937 }
Avinash Patile7f767a2013-01-03 21:21:32 -0800938 if ((mwifiex_pcie_txbd_not_full(card)) &&
939 tx_param->next_pkt_len) {
940 /* have more packets and TxBD still can hold more */
941 dev_dbg(adapter->dev,
942 "SEND DATA: delay dnld-rdy interrupt.\n");
943 adapter->data_sent = false;
944 } else {
945 /* Send the TX ready interrupt */
946 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
947 CPU_INTR_DNLD_RDY)) {
948 dev_err(adapter->dev,
949 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
950 ret = -1;
951 goto done_unmap;
952 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700953 }
954 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700955 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -0800956 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700957 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700958 dev_dbg(adapter->dev,
959 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700960 adapter->data_sent = true;
961 /* Send the TX ready interrupt */
962 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
963 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700964 dev_err(adapter->dev,
965 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700966 return -EBUSY;
967 }
968
Avinash Patile7f767a2013-01-03 21:21:32 -0800969 return -EINPROGRESS;
970done_unmap:
971 MWIFIEX_SKB_PACB(skb, &buf_pa);
972 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
973 card->tx_buf_list[wrindx] = NULL;
974 card->txbd_ring[wrindx]->paddr = 0;
975 card->txbd_ring[wrindx]->len = 0;
976 card->txbd_ring[wrindx]->flags = 0;
977 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700978}
979
980/*
981 * This function handles received buffer ring and
982 * dispatches packets to upper
983 */
984static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
985{
986 struct pcie_service_card *card = adapter->card;
987 u32 wrptr, rd_index;
Avinash Patile7f767a2013-01-03 21:21:32 -0800988 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700989 int ret = 0;
990 struct sk_buff *skb_tmp = NULL;
991
Avinash Patile7f767a2013-01-03 21:21:32 -0800992 if (!mwifiex_pcie_ok_to_access_hw(adapter))
993 mwifiex_pm_wakeup_card(adapter);
994
Amitkumar Karward930fae2011-10-11 17:41:21 -0700995 /* Read the RX ring Write pointer set by firmware */
996 if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700997 dev_err(adapter->dev,
998 "RECV DATA: failed to read REG_TXBD_RDPTR\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700999 ret = -1;
1000 goto done;
1001 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001002 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001003
1004 while (((wrptr & MWIFIEX_RXBD_MASK) !=
1005 (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) ||
1006 ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
1007 (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
1008 struct sk_buff *skb_data;
1009 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001010 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001011
1012 rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK;
1013 skb_data = card->rx_buf_list[rd_index];
1014
Avinash Patile7f767a2013-01-03 21:21:32 -08001015 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1016 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1017 PCI_DMA_FROMDEVICE);
1018 card->rx_buf_list[rd_index] = NULL;
1019
Amitkumar Karward930fae2011-10-11 17:41:21 -07001020 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001021 * first 2 bytes for len, next 2 bytes is for type
1022 */
1023 pkt_len = *((__le16 *)skb_data->data);
1024 rx_len = le16_to_cpu(pkt_len);
1025 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001026 dev_dbg(adapter->dev,
1027 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1028 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001029 skb_pull(skb_data, INTF_HEADER_LEN);
1030 mwifiex_handle_rx_packet(adapter, skb_data);
1031
1032 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001033 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001034 dev_err(adapter->dev,
1035 "Unable to allocate skb.\n");
1036 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001037 }
1038
Avinash Patile7f767a2013-01-03 21:21:32 -08001039 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1040 MWIFIEX_RX_DATA_BUF_SIZE,
1041 PCI_DMA_FROMDEVICE))
1042 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001043
Avinash Patile7f767a2013-01-03 21:21:32 -08001044 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1045
1046 dev_dbg(adapter->dev,
1047 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1048 skb_tmp, rd_index);
1049 card->rx_buf_list[rd_index] = skb_tmp;
1050 card->rxbd_ring[rd_index]->paddr = buf_pa;
1051 card->rxbd_ring[rd_index]->len = skb_tmp->len;
1052 card->rxbd_ring[rd_index]->flags = 0;
1053
Amitkumar Karward930fae2011-10-11 17:41:21 -07001054 if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) ==
1055 MWIFIEX_MAX_TXRX_BD) {
1056 card->rxbd_rdptr = ((card->rxbd_rdptr &
1057 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
1058 MWIFIEX_BD_FLAG_ROLLOVER_IND);
1059 }
1060 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001061 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001062
1063 /* Write the RX ring read pointer in to REG_RXBD_RDPTR */
1064 if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR,
1065 card->rxbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001066 dev_err(adapter->dev,
1067 "RECV DATA: failed to write REG_RXBD_RDPTR\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001068 ret = -1;
1069 goto done;
1070 }
1071
1072 /* Read the RX ring Write pointer set by firmware */
1073 if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001074 dev_err(adapter->dev,
1075 "RECV DATA: failed to read REG_TXBD_RDPTR\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001076 ret = -1;
1077 goto done;
1078 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001079 dev_dbg(adapter->dev,
1080 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001081 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001082 }
1083
1084done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001085 return ret;
1086}
1087
1088/*
1089 * This function downloads the boot command to device
1090 */
1091static int
1092mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1093{
Avinash Patilfc331462013-01-03 21:21:30 -08001094 dma_addr_t buf_pa;
1095 struct pcie_service_card *card = adapter->card;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001096
Avinash Patilfc331462013-01-03 21:21:30 -08001097 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001098 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001099 "Invalid parameter in %s <%p. len %d>\n",
1100 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001101 return -1;
1102 }
1103
Avinash Patilfc331462013-01-03 21:21:30 -08001104 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1105 return -1;
1106
1107 MWIFIEX_SKB_PACB(skb, &buf_pa);
1108
Amitkumar Karward930fae2011-10-11 17:41:21 -07001109 /* Write the lower 32bits of the physical address to scratch
1110 * register 0 */
Avinash Patilfc331462013-01-03 21:21:30 -08001111 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001112 dev_err(adapter->dev,
1113 "%s: failed to write download command to boot code.\n",
1114 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001115 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1116 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001117 return -1;
1118 }
1119
1120 /* Write the upper 32bits of the physical address to scratch
1121 * register 1 */
1122 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
Avinash Patilfc331462013-01-03 21:21:30 -08001123 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001124 dev_err(adapter->dev,
1125 "%s: failed to write download command to boot code.\n",
1126 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001127 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1128 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001129 return -1;
1130 }
1131
1132 /* Write the command length to scratch register 2 */
1133 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001134 dev_err(adapter->dev,
1135 "%s: failed to write command len to scratch reg 2\n",
1136 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001137 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1138 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001139 return -1;
1140 }
1141
1142 /* Ring the door bell */
1143 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1144 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001145 dev_err(adapter->dev,
1146 "%s: failed to assert door-bell intr\n", __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001147 pci_unmap_single(card->dev, buf_pa,
1148 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001149 return -1;
1150 }
1151
1152 return 0;
1153}
1154
Avinash Patilc6d1d872013-01-03 21:21:29 -08001155/* This function init rx port in firmware which in turn enables to receive data
1156 * from device before transmitting any packet.
1157 */
1158static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1159{
1160 struct pcie_service_card *card = adapter->card;
1161
1162 /* Write the RX ring read pointer in to REG_RXBD_RDPTR */
1163 if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr | 0)) {
1164 dev_err(adapter->dev,
1165 "RECV DATA: failed to write REG_RXBD_RDPTR\n");
1166 return -1;
1167 }
1168 return 0;
1169}
1170
1171/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001172 */
1173static int
1174mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1175{
1176 struct pcie_service_card *card = adapter->card;
1177 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001178 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1179 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001180
1181 if (!(skb->data && skb->len)) {
1182 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001183 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001184 return -1;
1185 }
1186
1187 /* Make sure a command response buffer is available */
1188 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001189 dev_err(adapter->dev,
1190 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001191 return -EBUSY;
1192 }
1193
Avinash Patilfc331462013-01-03 21:21:30 -08001194 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1195 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001196
1197 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001198
1199 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1200 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1201
1202 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1203 return -1;
1204
1205 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001206
1207 /* To send a command, the driver will:
1208 1. Write the 64bit physical address of the data buffer to
1209 SCRATCH1 + SCRATCH0
1210 2. Ring the door bell (i.e. set the door bell interrupt)
1211
1212 In response to door bell interrupt, the firmware will perform
1213 the DMA of the command packet (first header to obtain the total
1214 length and then rest of the command).
1215 */
1216
1217 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001218 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001219 /* Write the lower 32bits of the cmdrsp buffer physical
1220 address */
1221 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
Avinash Patilfc331462013-01-03 21:21:30 -08001222 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001223 dev_err(adapter->dev,
1224 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001225 ret = -1;
1226 goto done;
1227 }
1228 /* Write the upper 32bits of the cmdrsp buffer physical
1229 address */
1230 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
Avinash Patilfc331462013-01-03 21:21:30 -08001231 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001232 dev_err(adapter->dev,
1233 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001234 ret = -1;
1235 goto done;
1236 }
1237 }
1238
Avinash Patilfc331462013-01-03 21:21:30 -08001239 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001240 /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
Avinash Patilfc331462013-01-03 21:21:30 -08001241 if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001242 dev_err(adapter->dev,
1243 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001244 ret = -1;
1245 goto done;
1246 }
1247 /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
1248 if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
Avinash Patilfc331462013-01-03 21:21:30 -08001249 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001250 dev_err(adapter->dev,
1251 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001252 ret = -1;
1253 goto done;
1254 }
1255
1256 /* Write the command length to REG_CMD_SIZE */
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001257 if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) {
1258 dev_err(adapter->dev,
1259 "Failed to write cmd len to REG_CMD_SIZE\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001260 ret = -1;
1261 goto done;
1262 }
1263
1264 /* Ring the door bell */
1265 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1266 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001267 dev_err(adapter->dev,
1268 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001269 ret = -1;
1270 goto done;
1271 }
1272
1273done:
1274 if (ret)
1275 adapter->cmd_sent = false;
1276
1277 return 0;
1278}
1279
1280/*
1281 * This function handles command complete interrupt
1282 */
1283static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1284{
1285 struct pcie_service_card *card = adapter->card;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001286 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001287 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001288 u16 rx_len;
1289 __le16 pkt_len;
1290 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001291
1292 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1293
Avinash Patilfc331462013-01-03 21:21:30 -08001294 MWIFIEX_SKB_PACB(skb, &buf_pa);
1295 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1296 PCI_DMA_FROMDEVICE);
1297
1298 pkt_len = *((__le16 *)skb->data);
1299 rx_len = le16_to_cpu(pkt_len);
1300 skb_trim(skb, rx_len);
1301 skb_pull(skb, INTF_HEADER_LEN);
1302
Amitkumar Karward930fae2011-10-11 17:41:21 -07001303 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001304 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001305 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1306 skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001307 while (mwifiex_pcie_ok_to_access_hw(adapter) &&
1308 (count++ < 10))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001309 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001310 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001311 dev_err(adapter->dev,
1312 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001313 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001314 memcpy(adapter->upld_buf, skb->data,
1315 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patilfc331462013-01-03 21:21:30 -08001316 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1317 PCI_DMA_FROMDEVICE))
1318 return -1;
1319
1320 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001321 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001322 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001323 adapter->cmd_resp_received = true;
1324 /* Take the pointer and set it to CMD node and will
1325 return in the response complete callback */
1326 card->cmdrsp_buf = NULL;
1327
1328 /* Clear the cmd-rsp buffer address in scratch registers. This
1329 will prevent firmware from writing to the same response
1330 buffer again. */
1331 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001332 dev_err(adapter->dev,
1333 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001334 return -1;
1335 }
1336 /* Write the upper 32bits of the cmdrsp buffer physical
1337 address */
1338 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001339 dev_err(adapter->dev,
1340 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001341 return -1;
1342 }
1343 }
1344
1345 return 0;
1346}
1347
1348/*
1349 * Command Response processing complete handler
1350 */
1351static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1352 struct sk_buff *skb)
1353{
1354 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001355 dma_addr_t buf_pa;
1356 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001357
1358 if (skb) {
1359 card->cmdrsp_buf = skb;
1360 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001361 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1362 PCI_DMA_FROMDEVICE))
1363 return -1;
1364 }
1365
1366 skb_tmp = card->cmd_buf;
1367 if (skb_tmp) {
1368 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1369 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1370 PCI_DMA_FROMDEVICE);
1371 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001372 }
1373
1374 return 0;
1375}
1376
1377/*
1378 * This function handles firmware event ready interrupt
1379 */
1380static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1381{
1382 struct pcie_service_card *card = adapter->card;
1383 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1384 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001385 dma_addr_t buf_pa;
1386
1387 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1388 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001389
1390 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001391 dev_dbg(adapter->dev, "info: Event being processed, "
1392 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001393 return 0;
1394 }
1395
1396 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1397 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1398 return -1;
1399 }
1400
1401 /* Read the event ring write pointer set by firmware */
1402 if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001403 dev_err(adapter->dev,
1404 "EventReady: failed to read REG_EVTBD_WRPTR\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001405 return -1;
1406 }
1407
1408 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001409 card->evtbd_rdptr, wrptr);
1410 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1411 & MWIFIEX_EVTBD_MASK)) ||
Amitkumar Karward930fae2011-10-11 17:41:21 -07001412 ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
1413 (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
1414 struct sk_buff *skb_cmd;
1415 __le16 data_len = 0;
1416 u16 evt_len;
1417
1418 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1419 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001420 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1421 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1422 PCI_DMA_FROMDEVICE);
1423
Amitkumar Karward930fae2011-10-11 17:41:21 -07001424 /* Take the pointer and set it to event pointer in adapter
1425 and will return back after event handling callback */
1426 card->evt_buf_list[rdptr] = NULL;
1427 card->evtbd_ring[rdptr]->paddr = 0;
1428 card->evtbd_ring[rdptr]->len = 0;
1429 card->evtbd_ring[rdptr]->flags = 0;
1430
1431 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1432 adapter->event_cause = event;
1433 /* The first 4bytes will be the event transfer header
1434 len is 2 bytes followed by type which is 2 bytes */
1435 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1436 evt_len = le16_to_cpu(data_len);
1437
1438 skb_pull(skb_cmd, INTF_HEADER_LEN);
1439 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1440
1441 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1442 memcpy(adapter->event_body, skb_cmd->data +
1443 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1444 MWIFIEX_EVENT_HEADER_LEN);
1445
1446 adapter->event_received = true;
1447 adapter->event_skb = skb_cmd;
1448
1449 /* Do not update the event read pointer here, wait till the
1450 buffer is released. This is just to make things simpler,
1451 we need to find a better method of managing these buffers.
1452 */
1453 }
1454
1455 return 0;
1456}
1457
1458/*
1459 * Event processing complete handler
1460 */
1461static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1462 struct sk_buff *skb)
1463{
1464 struct pcie_service_card *card = adapter->card;
1465 int ret = 0;
1466 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1467 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001468 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001469
1470 if (!skb)
1471 return 0;
1472
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001473 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001474 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001475 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001476 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001477 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001478
1479 /* Read the event ring write pointer set by firmware */
1480 if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001481 dev_err(adapter->dev,
1482 "event_complete: failed to read REG_EVTBD_WRPTR\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001483 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001484 }
1485
1486 if (!card->evt_buf_list[rdptr]) {
1487 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001488 if (mwifiex_map_pci_memory(adapter, skb,
1489 MAX_EVENT_SIZE,
1490 PCI_DMA_FROMDEVICE))
1491 return -1;
1492 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001493 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001494 MWIFIEX_SKB_PACB(skb, &buf_pa);
1495 card->evtbd_ring[rdptr]->paddr = buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001496 card->evtbd_ring[rdptr]->len = (u16)skb->len;
1497 card->evtbd_ring[rdptr]->flags = 0;
1498 skb = NULL;
1499 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001500 dev_dbg(adapter->dev,
1501 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1502 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001503 }
1504
1505 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1506 card->evtbd_rdptr = ((card->evtbd_rdptr &
1507 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
1508 MWIFIEX_BD_FLAG_ROLLOVER_IND);
1509 }
1510
1511 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001512 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001513
1514 /* Write the event ring read pointer in to REG_EVTBD_RDPTR */
1515 if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001516 dev_err(adapter->dev,
1517 "event_complete: failed to read REG_EVTBD_RDPTR\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001518 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001519 }
1520
Amitkumar Karward930fae2011-10-11 17:41:21 -07001521 dev_dbg(adapter->dev, "info: Check Events Again\n");
1522 ret = mwifiex_pcie_process_event_ready(adapter);
1523
1524 return ret;
1525}
1526
1527/*
1528 * This function downloads the firmware to the card.
1529 *
1530 * Firmware is downloaded to the card in blocks. Every block download
1531 * is tested for CRC errors, and retried a number of times before
1532 * returning failure.
1533 */
1534static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1535 struct mwifiex_fw_image *fw)
1536{
1537 int ret;
1538 u8 *firmware = fw->fw_buf;
1539 u32 firmware_len = fw->fw_len;
1540 u32 offset = 0;
1541 struct sk_buff *skb;
1542 u32 txlen, tx_blocks = 0, tries, len;
1543 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001544 dma_addr_t buf_pa;
1545 struct pcie_service_card *card = adapter->card;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001546
1547 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001548 dev_err(adapter->dev,
1549 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001550 return -1;
1551 }
1552
1553 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001554 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001555
1556 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001557 dev_err(adapter->dev,
1558 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001559 return -1;
1560 }
1561
1562 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1563 if (!skb) {
1564 ret = -ENOMEM;
1565 goto done;
1566 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001567
1568 /* Perform firmware data transfer */
1569 do {
1570 u32 ireg_intr = 0;
1571
1572 /* More data? */
1573 if (offset >= firmware_len)
1574 break;
1575
1576 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
1577 ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG,
1578 &len);
1579 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001580 dev_warn(adapter->dev,
1581 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001582 goto done;
1583 }
1584 if (len)
1585 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001586 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001587 }
1588
1589 if (!len) {
1590 break;
1591 } else if (len > MWIFIEX_UPLD_SIZE) {
1592 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001593 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001594 ret = -1;
1595 goto done;
1596 }
1597
1598 txlen = len;
1599
1600 if (len & BIT(0)) {
1601 block_retry_cnt++;
1602 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1603 pr_err("FW download failure @ %d, over max "
1604 "retry count\n", offset);
1605 ret = -1;
1606 goto done;
1607 }
1608 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001609 "helper: len = 0x%04X, txlen = %d\n",
1610 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001611 len &= ~BIT(0);
1612 /* Setting this to 0 to resend from same offset */
1613 txlen = 0;
1614 } else {
1615 block_retry_cnt = 0;
1616 /* Set blocksize to transfer - checking for
1617 last block */
1618 if (firmware_len - offset < txlen)
1619 txlen = firmware_len - offset;
1620
1621 dev_dbg(adapter->dev, ".");
1622
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001623 tx_blocks = (txlen +
1624 MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
1625 MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001626
1627 /* Copy payload to buffer */
1628 memmove(skb->data, &firmware[offset], txlen);
1629 }
1630
1631 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
1632 skb_trim(skb, tx_blocks * MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD);
1633
1634 /* Send the boot command to device */
1635 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001636 dev_err(adapter->dev,
1637 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001638 ret = -1;
1639 goto done;
1640 }
Avinash Patilfc331462013-01-03 21:21:30 -08001641
1642 MWIFIEX_SKB_PACB(skb, &buf_pa);
1643
Amitkumar Karward930fae2011-10-11 17:41:21 -07001644 /* Wait for the command done interrupt */
1645 do {
1646 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1647 &ireg_intr)) {
1648 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001649 "interrupt status during fw dnld.\n",
1650 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001651 pci_unmap_single(card->dev, buf_pa, skb->len,
1652 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001653 ret = -1;
1654 goto done;
1655 }
1656 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1657 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001658
1659 pci_unmap_single(card->dev, buf_pa, skb->len,
1660 PCI_DMA_TODEVICE);
1661
Amitkumar Karward930fae2011-10-11 17:41:21 -07001662 offset += txlen;
1663 } while (true);
1664
1665 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001666 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001667
1668 ret = 0;
1669
1670done:
1671 dev_kfree_skb_any(skb);
1672 return ret;
1673}
1674
1675/*
1676 * This function checks the firmware status in card.
1677 *
1678 * The winner interface is also determined by this function.
1679 */
1680static int
1681mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1682{
1683 int ret = 0;
1684 u32 firmware_stat, winner_status;
1685 u32 tries;
1686
1687 /* Mask spurios interrupts */
1688 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001689 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001690 dev_warn(adapter->dev, "Write register failed\n");
1691 return -1;
1692 }
1693
1694 dev_dbg(adapter->dev, "Setting driver ready signature\n");
1695 if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001696 dev_err(adapter->dev,
1697 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001698 return -1;
1699 }
1700
1701 /* Wait for firmware initialization event */
1702 for (tries = 0; tries < poll_num; tries++) {
1703 if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
1704 &firmware_stat))
1705 ret = -1;
1706 else
1707 ret = 0;
1708 if (ret)
1709 continue;
1710 if (firmware_stat == FIRMWARE_READY_PCIE) {
1711 ret = 0;
1712 break;
1713 } else {
1714 mdelay(100);
1715 ret = -1;
1716 }
1717 }
1718
1719 if (ret) {
1720 if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
1721 &winner_status))
1722 ret = -1;
1723 else if (!winner_status) {
1724 dev_err(adapter->dev, "PCI-E is the winner\n");
1725 adapter->winner = 1;
1726 ret = -1;
1727 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001728 dev_err(adapter->dev,
1729 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1730 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001731 ret = 0;
1732 }
1733 }
1734
1735 return ret;
1736}
1737
1738/*
1739 * This function reads the interrupt status from card.
1740 */
1741static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1742{
1743 u32 pcie_ireg;
1744 unsigned long flags;
1745
1746 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1747 return;
1748
1749 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1750 dev_warn(adapter->dev, "Read register failed\n");
1751 return;
1752 }
1753
1754 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1755
1756 mwifiex_pcie_disable_host_int(adapter);
1757
1758 /* Clear the pending interrupts */
1759 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1760 ~pcie_ireg)) {
1761 dev_warn(adapter->dev, "Write register failed\n");
1762 return;
1763 }
1764 spin_lock_irqsave(&adapter->int_lock, flags);
1765 adapter->int_status |= pcie_ireg;
1766 spin_unlock_irqrestore(&adapter->int_lock, flags);
1767
1768 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1769 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1770 (adapter->ps_state == PS_STATE_SLEEP)) {
1771 mwifiex_pcie_enable_host_int(adapter);
1772 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001773 PCIE_CPU_INT_EVENT,
1774 CPU_INTR_SLEEP_CFM_DONE)
1775 ) {
1776 dev_warn(adapter->dev,
1777 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001778 return;
1779
1780 }
1781 }
1782 } else if (!adapter->pps_uapsd_mode &&
1783 adapter->ps_state == PS_STATE_SLEEP) {
1784 /* Potentially for PCIe we could get other
1785 * interrupts like shared. Don't change power
1786 * state until cookie is set */
1787 if (mwifiex_pcie_ok_to_access_hw(adapter))
1788 adapter->ps_state = PS_STATE_AWAKE;
1789 }
1790 }
1791}
1792
1793/*
1794 * Interrupt handler for PCIe root port
1795 *
1796 * This function reads the interrupt status from firmware and assigns
1797 * the main process in workqueue which will handle the interrupt.
1798 */
1799static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
1800{
1801 struct pci_dev *pdev = (struct pci_dev *)context;
1802 struct pcie_service_card *card;
1803 struct mwifiex_adapter *adapter;
1804
1805 if (!pdev) {
1806 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
1807 goto exit;
1808 }
1809
1810 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
1811 if (!card || !card->adapter) {
1812 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001813 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001814 goto exit;
1815 }
1816 adapter = card->adapter;
1817
1818 if (adapter->surprise_removed)
1819 goto exit;
1820
1821 mwifiex_interrupt_status(adapter);
1822 queue_work(adapter->workqueue, &adapter->main_work);
1823
1824exit:
1825 return IRQ_HANDLED;
1826}
1827
1828/*
1829 * This function checks the current interrupt status.
1830 *
1831 * The following interrupts are checked and handled by this function -
1832 * - Data sent
1833 * - Command sent
1834 * - Command received
1835 * - Packets received
1836 * - Events received
1837 *
1838 * In case of Rx packets received, the packets are uploaded from card to
1839 * host and processed accordingly.
1840 */
1841static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1842{
1843 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08001844 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001845 unsigned long flags;
1846
1847 spin_lock_irqsave(&adapter->int_lock, flags);
1848 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08001849 pcie_ireg = adapter->int_status;
1850 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001851 spin_unlock_irqrestore(&adapter->int_lock, flags);
1852
Avinash Patil659c4782013-01-03 21:21:28 -08001853 while (pcie_ireg & HOST_INTR_MASK) {
1854 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
1855 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08001856 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
1857 ret = mwifiex_pcie_send_data_complete(adapter);
1858 if (ret)
1859 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001860 }
Avinash Patil659c4782013-01-03 21:21:28 -08001861 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
1862 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001863 dev_dbg(adapter->dev, "info: Rx DATA\n");
1864 ret = mwifiex_pcie_process_recv_data(adapter);
1865 if (ret)
1866 return ret;
1867 }
Avinash Patil659c4782013-01-03 21:21:28 -08001868 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
1869 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001870 dev_dbg(adapter->dev, "info: Rx EVENT\n");
1871 ret = mwifiex_pcie_process_event_ready(adapter);
1872 if (ret)
1873 return ret;
1874 }
1875
Avinash Patil659c4782013-01-03 21:21:28 -08001876 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1877 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001878 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001879 dev_dbg(adapter->dev,
1880 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001881 adapter->cmd_sent = false;
1882 }
1883 /* Handle command response */
1884 ret = mwifiex_pcie_process_cmd_complete(adapter);
1885 if (ret)
1886 return ret;
1887 }
1888
1889 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1890 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
1891 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001892 dev_warn(adapter->dev,
1893 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001894 return -1;
1895 }
1896
1897 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1898 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001899 PCIE_HOST_INT_STATUS,
1900 ~pcie_ireg)) {
1901 dev_warn(adapter->dev,
1902 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001903 return -1;
1904 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001905 }
1906
1907 }
1908 }
1909 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001910 adapter->cmd_sent, adapter->data_sent);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001911 mwifiex_pcie_enable_host_int(adapter);
1912
1913 return 0;
1914}
1915
1916/*
1917 * This function downloads data from driver to card.
1918 *
1919 * Both commands and data packets are transferred to the card by this
1920 * function.
1921 *
1922 * This function adds the PCIE specific header to the front of the buffer
1923 * before transferring. The header contains the length of the packet and
1924 * the type. The firmware handles the packets based upon this set type.
1925 */
1926static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
1927 struct sk_buff *skb,
1928 struct mwifiex_tx_param *tx_param)
1929{
Dan Carpenterfa161cb72011-11-07 19:31:45 -08001930 if (!skb) {
1931 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001932 return -1;
1933 }
1934
1935 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08001936 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001937 else if (type == MWIFIEX_TYPE_CMD)
1938 return mwifiex_pcie_send_cmd(adapter, skb);
1939
1940 return 0;
1941}
1942
1943/*
1944 * This function initializes the PCI-E host memory space, WCB rings, etc.
1945 *
1946 * The following initializations steps are followed -
1947 * - Allocate TXBD ring buffers
1948 * - Allocate RXBD ring buffers
1949 * - Allocate event BD ring buffers
1950 * - Allocate command response ring buffer
1951 * - Allocate sleep cookie buffer
1952 */
1953static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
1954{
1955 struct pcie_service_card *card = adapter->card;
1956 int ret;
1957 struct pci_dev *pdev = card->dev;
1958
1959 pci_set_drvdata(pdev, card);
1960
1961 ret = pci_enable_device(pdev);
1962 if (ret)
1963 goto err_enable_dev;
1964
1965 pci_set_master(pdev);
1966
1967 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
1968 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
1969 if (ret) {
1970 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
1971 goto err_set_dma_mask;
1972 }
1973
1974 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
1975 if (ret) {
1976 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
1977 goto err_set_dma_mask;
1978 }
1979
1980 ret = pci_request_region(pdev, 0, DRV_NAME);
1981 if (ret) {
1982 dev_err(adapter->dev, "req_reg(0) error\n");
1983 goto err_req_region0;
1984 }
1985 card->pci_mmap = pci_iomap(pdev, 0, 0);
1986 if (!card->pci_mmap) {
1987 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04001988 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001989 goto err_iomap0;
1990 }
1991 ret = pci_request_region(pdev, 2, DRV_NAME);
1992 if (ret) {
1993 dev_err(adapter->dev, "req_reg(2) error\n");
1994 goto err_req_region2;
1995 }
1996 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
1997 if (!card->pci_mmap1) {
1998 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04001999 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002000 goto err_iomap2;
2001 }
2002
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002003 dev_dbg(adapter->dev,
2004 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2005 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002006
2007 card->cmdrsp_buf = NULL;
2008 ret = mwifiex_pcie_create_txbd_ring(adapter);
2009 if (ret)
2010 goto err_cre_txbd;
2011 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2012 if (ret)
2013 goto err_cre_rxbd;
2014 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2015 if (ret)
2016 goto err_cre_evtbd;
2017 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2018 if (ret)
2019 goto err_alloc_cmdbuf;
2020 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2021 if (ret)
2022 goto err_alloc_cookie;
2023
2024 return ret;
2025
2026err_alloc_cookie:
2027 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2028err_alloc_cmdbuf:
2029 mwifiex_pcie_delete_evtbd_ring(adapter);
2030err_cre_evtbd:
2031 mwifiex_pcie_delete_rxbd_ring(adapter);
2032err_cre_rxbd:
2033 mwifiex_pcie_delete_txbd_ring(adapter);
2034err_cre_txbd:
2035 pci_iounmap(pdev, card->pci_mmap1);
2036err_iomap2:
2037 pci_release_region(pdev, 2);
2038err_req_region2:
2039 pci_iounmap(pdev, card->pci_mmap);
2040err_iomap0:
2041 pci_release_region(pdev, 0);
2042err_req_region0:
2043err_set_dma_mask:
2044 pci_disable_device(pdev);
2045err_enable_dev:
2046 pci_set_drvdata(pdev, NULL);
2047 return ret;
2048}
2049
2050/*
2051 * This function cleans up the allocated card buffers.
2052 *
2053 * The following are freed by this function -
2054 * - TXBD ring buffers
2055 * - RXBD ring buffers
2056 * - Event BD ring buffers
2057 * - Command response ring buffer
2058 * - Sleep cookie buffer
2059 */
2060static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2061{
2062 struct pcie_service_card *card = adapter->card;
2063 struct pci_dev *pdev = card->dev;
2064
Amitkumar Karward930fae2011-10-11 17:41:21 -07002065 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002066 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002067 if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002068 dev_err(adapter->dev,
2069 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002070 }
2071
2072 if (pdev) {
2073 pci_iounmap(pdev, card->pci_mmap);
2074 pci_iounmap(pdev, card->pci_mmap1);
2075
2076 pci_release_regions(pdev);
2077 pci_disable_device(pdev);
2078 pci_set_drvdata(pdev, NULL);
2079 }
2080}
2081
2082/*
2083 * This function registers the PCIE device.
2084 *
2085 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2086 */
2087static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2088{
2089 int ret;
2090 struct pcie_service_card *card = adapter->card;
2091 struct pci_dev *pdev = card->dev;
2092
2093 /* save adapter pointer in card */
2094 card->adapter = adapter;
2095
2096 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2097 "MRVL_PCIE", pdev);
2098 if (ret) {
2099 pr_err("request_irq failed: ret=%d\n", ret);
2100 adapter->card = NULL;
2101 return -1;
2102 }
2103
2104 adapter->dev = &pdev->dev;
2105 strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME);
2106
2107 return 0;
2108}
2109
2110/*
2111 * This function unregisters the PCIE device.
2112 *
2113 * The PCIE IRQ is released, the function is disabled and driver
2114 * data is set to null.
2115 */
2116static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2117{
2118 struct pcie_service_card *card = adapter->card;
2119
2120 if (card) {
2121 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2122 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002123
2124 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2125 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2126 mwifiex_pcie_delete_evtbd_ring(adapter);
2127 mwifiex_pcie_delete_rxbd_ring(adapter);
2128 mwifiex_pcie_delete_txbd_ring(adapter);
2129 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002130 }
2131}
2132
2133static struct mwifiex_if_ops pcie_ops = {
2134 .init_if = mwifiex_pcie_init,
2135 .cleanup_if = mwifiex_pcie_cleanup,
2136 .check_fw_status = mwifiex_check_fw_status,
2137 .prog_fw = mwifiex_prog_fw_w_helper,
2138 .register_dev = mwifiex_register_dev,
2139 .unregister_dev = mwifiex_unregister_dev,
2140 .enable_int = mwifiex_pcie_enable_host_int,
2141 .process_int_status = mwifiex_process_int_status,
2142 .host_to_card = mwifiex_pcie_host_to_card,
2143 .wakeup = mwifiex_pm_wakeup_card,
2144 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2145
2146 /* PCIE specific */
2147 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2148 .event_complete = mwifiex_pcie_event_complete,
2149 .update_mp_end_port = NULL,
2150 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002151 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002152 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002153};
2154
2155/*
2156 * This function initializes the PCIE driver module.
2157 *
2158 * This initiates the semaphore and registers the device with
2159 * PCIE bus.
2160 */
2161static int mwifiex_pcie_init_module(void)
2162{
2163 int ret;
2164
2165 pr_debug("Marvell 8766 PCIe Driver\n");
2166
2167 sema_init(&add_remove_card_sem, 1);
2168
2169 /* Clear the flag in case user removes the card. */
2170 user_rmmod = 0;
2171
2172 ret = pci_register_driver(&mwifiex_pcie);
2173 if (ret)
2174 pr_err("Driver register failed!\n");
2175 else
2176 pr_debug("info: Driver registered successfully!\n");
2177
2178 return ret;
2179}
2180
2181/*
2182 * This function cleans up the PCIE driver.
2183 *
2184 * The following major steps are followed for cleanup -
2185 * - Resume the device if its suspended
2186 * - Disconnect the device if connected
2187 * - Shutdown the firmware
2188 * - Unregister the device from PCIE bus.
2189 */
2190static void mwifiex_pcie_cleanup_module(void)
2191{
2192 if (!down_interruptible(&add_remove_card_sem))
2193 up(&add_remove_card_sem);
2194
2195 /* Set the flag as user is removing this module. */
2196 user_rmmod = 1;
2197
2198 pci_unregister_driver(&mwifiex_pcie);
2199}
2200
2201module_init(mwifiex_pcie_init_module);
2202module_exit(mwifiex_pcie_cleanup_module);
2203
2204MODULE_AUTHOR("Marvell International Ltd.");
2205MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2206MODULE_VERSION(PCIE_VERSION);
2207MODULE_LICENSE("GPL v2");
2208MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin");