blob: 57c353a94b29784f990c7e62c5e8e2dd2bb36b46 [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,
Aaron Durbindbccc922014-02-07 16:25:50 -080042 size_t 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;
Aaron Durbindbccc922014-02-07 16:25:50 -080045 struct mwifiex_dma_mapping mapping;
Amitkumar Karward930fae2011-10-11 17:41:21 -070046
Aaron Durbindbccc922014-02-07 16:25:50 -080047 mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
48 if (pci_dma_mapping_error(card->dev, mapping.addr)) {
Avinash Patilfc331462013-01-03 21:21:30 -080049 dev_err(adapter->dev, "failed to map pci memory!\n");
50 return -1;
51 }
Aaron Durbindbccc922014-02-07 16:25:50 -080052 mapping.len = size;
53 memcpy(skb->cb, &mapping, sizeof(mapping));
Avinash Patilfc331462013-01-03 21:21:30 -080054 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070055}
56
Aaron Durbindbccc922014-02-07 16:25:50 -080057static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
58 struct sk_buff *skb, int flags)
59{
60 struct pcie_service_card *card = adapter->card;
61 struct mwifiex_dma_mapping mapping;
62
63 MWIFIEX_SKB_PACB(skb, &mapping);
64 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
65}
66
Amitkumar Karward930fae2011-10-11 17:41:21 -070067/*
68 * This function reads sleep cookie and checks if FW is ready
69 */
70static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
71{
72 u32 *cookie_addr;
73 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080074 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
75
76 if (!reg->sleep_cookie)
77 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070078
Avinash Patilfc331462013-01-03 21:21:30 -080079 if (card->sleep_cookie_vbase) {
80 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070081 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
82 *cookie_addr);
83 if (*cookie_addr == FW_AWAKE_COOKIE)
84 return true;
85 }
86
87 return false;
88}
89
Shuah Khan3266d732013-07-03 10:47:10 -060090#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -070091/*
Bing Zhaofcca8d52013-03-04 16:27:53 -080092 * Kernel needs to suspend all functions separately. Therefore all
93 * registered functions must have drivers with suspend and resume
94 * methods. Failing that the kernel simply removes the whole card.
95 *
96 * If already not suspended, this function allocates and sends a host
97 * sleep activate request to the firmware and turns off the traffic.
98 */
Shuah Khan3266d732013-07-03 10:47:10 -060099static int mwifiex_pcie_suspend(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800100{
101 struct mwifiex_adapter *adapter;
102 struct pcie_service_card *card;
103 int hs_actived;
Shuah Khan3266d732013-07-03 10:47:10 -0600104 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800105
106 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900107 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800108 if (!card || !card->adapter) {
109 pr_err("Card or adapter structure is not valid\n");
110 return 0;
111 }
112 } else {
113 pr_err("PCIE device is not specified\n");
114 return 0;
115 }
116
117 adapter = card->adapter;
118
119 hs_actived = mwifiex_enable_hs(adapter);
120
121 /* Indicate device suspended */
122 adapter->is_suspended = true;
123
124 return 0;
125}
126
127/*
128 * Kernel needs to suspend all functions separately. Therefore all
129 * registered functions must have drivers with suspend and resume
130 * methods. Failing that the kernel simply removes the whole card.
131 *
132 * If already not resumed, this function turns on the traffic and
133 * sends a host sleep cancel request to the firmware.
134 */
Shuah Khan3266d732013-07-03 10:47:10 -0600135static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800136{
137 struct mwifiex_adapter *adapter;
138 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600139 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800140
141 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900142 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800143 if (!card || !card->adapter) {
144 pr_err("Card or adapter structure is not valid\n");
145 return 0;
146 }
147 } else {
148 pr_err("PCIE device is not specified\n");
149 return 0;
150 }
151
152 adapter = card->adapter;
153
154 if (!adapter->is_suspended) {
155 dev_warn(adapter->dev, "Device already resumed\n");
156 return 0;
157 }
158
159 adapter->is_suspended = false;
160
161 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
162 MWIFIEX_ASYNC_CMD);
163
164 return 0;
165}
Bing Zhao8509e822013-03-04 16:27:54 -0800166#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800167
168/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700169 * This function probes an mwifiex device and registers it. It allocates
170 * the card structure, enables PCIE function number and initiates the
171 * device registration and initialization procedure by adding a logical
172 * interface.
173 */
174static int mwifiex_pcie_probe(struct pci_dev *pdev,
175 const struct pci_device_id *ent)
176{
177 struct pcie_service_card *card;
178
179 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700180 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700181
182 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000183 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700184 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700185
186 card->dev = pdev;
187
Avinash Patildd04e6a2013-02-08 18:18:06 -0800188 if (ent->driver_data) {
189 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
190 card->pcie.firmware = data->firmware;
191 card->pcie.reg = data->reg;
192 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
Amitkumar Karwar828cf222014-02-27 19:35:13 -0800193 card->pcie.tx_buf_size = data->tx_buf_size;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800194 }
195
Amitkumar Karward930fae2011-10-11 17:41:21 -0700196 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
197 MWIFIEX_PCIE)) {
198 pr_err("%s failed\n", __func__);
199 kfree(card);
200 return -1;
201 }
202
203 return 0;
204}
205
206/*
207 * This function removes the interface and frees up the card structure.
208 */
209static void mwifiex_pcie_remove(struct pci_dev *pdev)
210{
211 struct pcie_service_card *card;
212 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700213 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700214
215 card = pci_get_drvdata(pdev);
216 if (!card)
217 return;
218
219 adapter = card->adapter;
220 if (!adapter || !adapter->priv_num)
221 return;
222
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700223 /* In case driver is removed when asynchronous FW load is in progress */
224 wait_for_completion(&adapter->fw_load);
225
Amitkumar Karward930fae2011-10-11 17:41:21 -0700226 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600227#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700228 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600229 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700230#endif
231
Amitkumar Karwar848819f2014-02-27 19:35:17 -0800232 mwifiex_deauthenticate_all(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700233
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700234 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700235
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700236 mwifiex_disable_auto_ds(priv);
237
238 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700239 }
240
241 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700242}
243
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700244static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
245{
246 user_rmmod = 1;
247 mwifiex_pcie_remove(pdev);
248
249 return;
250}
251
Amitkumar Karward930fae2011-10-11 17:41:21 -0700252static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
253 {
254 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
255 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800256 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700257 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800258 {
259 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
260 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
261 .driver_data = (unsigned long) &mwifiex_pcie8897,
262 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700263 {},
264};
265
266MODULE_DEVICE_TABLE(pci, mwifiex_ids);
267
Shuah Khan3266d732013-07-03 10:47:10 -0600268#ifdef CONFIG_PM_SLEEP
269/* Power Management Hooks */
270static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
271 mwifiex_pcie_resume);
272#endif
273
Amitkumar Karward930fae2011-10-11 17:41:21 -0700274/* PCI Device Driver */
275static struct pci_driver __refdata mwifiex_pcie = {
276 .name = "mwifiex_pcie",
277 .id_table = mwifiex_ids,
278 .probe = mwifiex_pcie_probe,
279 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600280#ifdef CONFIG_PM_SLEEP
281 .driver = {
282 .pm = &mwifiex_pcie_pm_ops,
283 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700284#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700285 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700286};
287
288/*
289 * This function writes data into PCIE card register.
290 */
291static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
292{
293 struct pcie_service_card *card = adapter->card;
294
295 iowrite32(data, card->pci_mmap1 + reg);
296
297 return 0;
298}
299
300/*
301 * This function reads data from PCIE card register.
302 */
303static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
304{
305 struct pcie_service_card *card = adapter->card;
306
307 *data = ioread32(card->pci_mmap1 + reg);
308
309 return 0;
310}
311
312/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700313 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700314 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700315static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700316{
317 int i = 0;
318
Avinash Patilc0880a22013-03-22 21:49:07 -0700319 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700320 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700321 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700322 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800323 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700324 break;
325 }
326
Avinash Patilc0880a22013-03-22 21:49:07 -0700327 return;
328}
329
Avinash Patilc4bc9802014-03-18 22:19:17 -0700330static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
331 u32 max_delay_loop_cnt)
332{
333 struct pcie_service_card *card = adapter->card;
334 u8 *buffer;
335 u32 sleep_cookie, count;
336
337 for (count = 0; count < max_delay_loop_cnt; count++) {
338 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
339 sleep_cookie = *(u32 *)buffer;
340
341 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
342 dev_dbg(adapter->dev,
343 "sleep cookie found at count %d\n", count);
344 break;
345 }
346 usleep_range(20, 30);
347 }
348
349 if (count >= max_delay_loop_cnt)
350 dev_dbg(adapter->dev,
351 "max count reached while accessing sleep cookie\n");
352}
353
Avinash Patilc0880a22013-03-22 21:49:07 -0700354/* This function wakes up the card by reading fw_status register. */
355static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
356{
357 u32 fw_status;
358 struct pcie_service_card *card = adapter->card;
359 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
360
Amitkumar Karward930fae2011-10-11 17:41:21 -0700361 dev_dbg(adapter->dev, "event: Wakeup device...\n");
362
Avinash Patilc0880a22013-03-22 21:49:07 -0700363 if (reg->sleep_cookie)
364 mwifiex_pcie_dev_wakeup_delay(adapter);
365
366 /* Reading fw_status register will wakeup device */
367 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
368 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700369 return -1;
370 }
371
Avinash Patilc0880a22013-03-22 21:49:07 -0700372 if (reg->sleep_cookie) {
373 mwifiex_pcie_dev_wakeup_delay(adapter);
374 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
375 adapter->ps_state = PS_STATE_AWAKE;
376 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700377
378 return 0;
379}
380
381/*
382 * This function is called after the card has woken up.
383 *
384 * The card configuration register is reset.
385 */
386static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
387{
388 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
389
390 return 0;
391}
392
393/*
394 * This function disables the host interrupt.
395 *
396 * The host interrupt mask is read, the disable bit is reset and
397 * written back to the card host interrupt mask register.
398 */
399static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
400{
401 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
402 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
403 0x00000000)) {
404 dev_warn(adapter->dev, "Disable host interrupt failed\n");
405 return -1;
406 }
407 }
408
409 return 0;
410}
411
412/*
413 * This function enables the host interrupt.
414 *
415 * The host interrupt enable mask is written to the card
416 * host interrupt mask register.
417 */
418static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
419{
420 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
421 /* Simply write the mask to the register */
422 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
423 HOST_INTR_MASK)) {
424 dev_warn(adapter->dev, "Enable host interrupt failed\n");
425 return -1;
426 }
427 }
428
429 return 0;
430}
431
432/*
Avinash Patil07324842013-02-08 18:18:07 -0800433 * This function initializes TX buffer ring descriptors
434 */
435static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
436{
437 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800438 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800439 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800440 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800441 int i;
442
443 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
444 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800445 if (reg->pfu_enabled) {
446 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
447 (sizeof(*desc2) * i);
448 desc2 = card->txbd_ring[i];
449 memset(desc2, 0, sizeof(*desc2));
450 } else {
451 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
452 (sizeof(*desc) * i);
453 desc = card->txbd_ring[i];
454 memset(desc, 0, sizeof(*desc));
455 }
Avinash Patil07324842013-02-08 18:18:07 -0800456 }
457
458 return 0;
459}
460
461/* This function initializes RX buffer ring descriptors. Each SKB is allocated
462 * here and after mapping PCI memory, its physical address is assigned to
463 * PCIE Rx buffer descriptor's physical address.
464 */
465static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
466{
467 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800468 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800469 struct sk_buff *skb;
470 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800471 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800472 dma_addr_t buf_pa;
473 int i;
474
475 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
476 /* Allocate skb here so that firmware can DMA data from it */
477 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
478 if (!skb) {
479 dev_err(adapter->dev,
480 "Unable to allocate skb for RX ring.\n");
481 kfree(card->rxbd_ring_vbase);
482 return -ENOMEM;
483 }
484
485 if (mwifiex_map_pci_memory(adapter, skb,
486 MWIFIEX_RX_DATA_BUF_SIZE,
487 PCI_DMA_FROMDEVICE))
488 return -1;
489
Aaron Durbindbccc922014-02-07 16:25:50 -0800490 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800491
492 dev_dbg(adapter->dev,
493 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
494 skb, skb->len, skb->data, (u32)buf_pa,
495 (u32)((u64)buf_pa >> 32));
496
497 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800498 if (reg->pfu_enabled) {
499 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
500 (sizeof(*desc2) * i);
501 desc2 = card->rxbd_ring[i];
502 desc2->paddr = buf_pa;
503 desc2->len = (u16)skb->len;
504 desc2->frag_len = (u16)skb->len;
505 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
506 desc2->offset = 0;
507 } else {
508 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
509 (sizeof(*desc) * i));
510 desc = card->rxbd_ring[i];
511 desc->paddr = buf_pa;
512 desc->len = (u16)skb->len;
513 desc->flags = 0;
514 }
Avinash Patil07324842013-02-08 18:18:07 -0800515 }
516
517 return 0;
518}
519
520/* This function initializes event buffer ring descriptors. Each SKB is
521 * allocated here and after mapping PCI memory, its physical address is assigned
522 * to PCIE Rx buffer descriptor's physical address
523 */
524static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
525{
526 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800527 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800528 struct sk_buff *skb;
529 dma_addr_t buf_pa;
530 int i;
531
532 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
533 /* Allocate skb here so that firmware can DMA data from it */
534 skb = dev_alloc_skb(MAX_EVENT_SIZE);
535 if (!skb) {
536 dev_err(adapter->dev,
537 "Unable to allocate skb for EVENT buf.\n");
538 kfree(card->evtbd_ring_vbase);
539 return -ENOMEM;
540 }
541 skb_put(skb, MAX_EVENT_SIZE);
542
543 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
544 PCI_DMA_FROMDEVICE))
545 return -1;
546
Aaron Durbindbccc922014-02-07 16:25:50 -0800547 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800548
549 dev_dbg(adapter->dev,
550 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
551 skb, skb->len, skb->data, (u32)buf_pa,
552 (u32)((u64)buf_pa >> 32));
553
554 card->evt_buf_list[i] = skb;
555 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
556 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800557 desc = card->evtbd_ring[i];
558 desc->paddr = buf_pa;
559 desc->len = (u16)skb->len;
560 desc->flags = 0;
561 }
562
563 return 0;
564}
565
566/* This function cleans up TX buffer rings. If any of the buffer list has valid
567 * SKB address, associated SKB is freed.
568 */
569static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
570{
571 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800572 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800573 struct sk_buff *skb;
574 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800575 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800576 int i;
577
578 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800579 if (reg->pfu_enabled) {
580 desc2 = card->txbd_ring[i];
581 if (card->tx_buf_list[i]) {
582 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800583 mwifiex_unmap_pci_memory(adapter, skb,
584 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800585 dev_kfree_skb_any(skb);
586 }
587 memset(desc2, 0, sizeof(*desc2));
588 } else {
589 desc = card->txbd_ring[i];
590 if (card->tx_buf_list[i]) {
591 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800592 mwifiex_unmap_pci_memory(adapter, skb,
593 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800594 dev_kfree_skb_any(skb);
595 }
596 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800597 }
598 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800599 }
600
601 return;
602}
603
604/* This function cleans up RX buffer rings. If any of the buffer list has valid
605 * SKB address, associated SKB is freed.
606 */
607static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
608{
609 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800610 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800611 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800612 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800613 struct sk_buff *skb;
614 int i;
615
616 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800617 if (reg->pfu_enabled) {
618 desc2 = card->rxbd_ring[i];
619 if (card->rx_buf_list[i]) {
620 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800621 mwifiex_unmap_pci_memory(adapter, skb,
622 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800623 dev_kfree_skb_any(skb);
624 }
625 memset(desc2, 0, sizeof(*desc2));
626 } else {
627 desc = card->rxbd_ring[i];
628 if (card->rx_buf_list[i]) {
629 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800630 mwifiex_unmap_pci_memory(adapter, skb,
631 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800632 dev_kfree_skb_any(skb);
633 }
634 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800635 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800636 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800637 }
638
639 return;
640}
641
642/* This function cleans up event buffer rings. If any of the buffer list has
643 * valid SKB address, associated SKB is freed.
644 */
645static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
646{
647 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800648 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800649 struct sk_buff *skb;
650 int i;
651
652 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
653 desc = card->evtbd_ring[i];
654 if (card->evt_buf_list[i]) {
655 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800656 mwifiex_unmap_pci_memory(adapter, skb,
657 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800658 dev_kfree_skb_any(skb);
659 }
660 card->evt_buf_list[i] = NULL;
661 memset(desc, 0, sizeof(*desc));
662 }
663
664 return;
665}
666
667/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700668 */
669static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
670{
671 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800672 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700673
674 /*
675 * driver maintaines the write pointer and firmware maintaines the read
676 * pointer. The write pointer starts at 0 (zero) while the read pointer
677 * starts at zero with rollover bit set
678 */
679 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800680
681 if (reg->pfu_enabled)
682 card->txbd_rdptr = 0;
683 else
684 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700685
686 /* allocate shared memory for the BD ring and divide the same in to
687 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800688 if (reg->pfu_enabled)
689 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
690 MWIFIEX_MAX_TXRX_BD;
691 else
692 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
693 MWIFIEX_MAX_TXRX_BD;
694
Amitkumar Karward930fae2011-10-11 17:41:21 -0700695 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700696 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800697 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
698 card->txbd_ring_size,
699 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700700 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800701 dev_err(adapter->dev,
702 "allocate consistent memory (%d bytes) failed!\n",
703 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800704 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700705 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700706 dev_dbg(adapter->dev,
707 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800708 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700709 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700710
Avinash Patil07324842013-02-08 18:18:07 -0800711 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700712}
713
714static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
715{
716 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800717 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700718
Avinash Patil07324842013-02-08 18:18:07 -0800719 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700720
Avinash Patilfc331462013-01-03 21:21:30 -0800721 if (card->txbd_ring_vbase)
722 pci_free_consistent(card->dev, card->txbd_ring_size,
723 card->txbd_ring_vbase,
724 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700725 card->txbd_ring_size = 0;
726 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800727 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700728 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800729 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700730
731 return 0;
732}
733
734/*
735 * This function creates buffer descriptor ring for RX
736 */
737static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
738{
739 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800740 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700741
742 /*
743 * driver maintaines the read pointer and firmware maintaines the write
744 * pointer. The write pointer starts at 0 (zero) while the read pointer
745 * starts at zero with rollover bit set
746 */
747 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800748 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700749
Avinash Patilca8f2112013-02-08 18:18:09 -0800750 if (reg->pfu_enabled)
751 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
752 MWIFIEX_MAX_TXRX_BD;
753 else
754 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
755 MWIFIEX_MAX_TXRX_BD;
756
Amitkumar Karward930fae2011-10-11 17:41:21 -0700757 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700758 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800759 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
760 card->rxbd_ring_size,
761 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700762 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800763 dev_err(adapter->dev,
764 "allocate consistent memory (%d bytes) failed!\n",
765 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800766 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700767 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700768
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700769 dev_dbg(adapter->dev,
770 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
771 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
772 (u32)((u64)card->rxbd_ring_pbase >> 32),
773 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700774
Avinash Patil07324842013-02-08 18:18:07 -0800775 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700776}
777
778/*
779 * This function deletes Buffer descriptor ring for RX
780 */
781static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
782{
783 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800784 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700785
Avinash Patil07324842013-02-08 18:18:07 -0800786 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700787
Avinash Patilfc331462013-01-03 21:21:30 -0800788 if (card->rxbd_ring_vbase)
789 pci_free_consistent(card->dev, card->rxbd_ring_size,
790 card->rxbd_ring_vbase,
791 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700792 card->rxbd_ring_size = 0;
793 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800794 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700795 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800796 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700797
798 return 0;
799}
800
801/*
802 * This function creates buffer descriptor ring for Events
803 */
804static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
805{
806 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800807 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700808
809 /*
810 * driver maintaines the read pointer and firmware maintaines the write
811 * pointer. The write pointer starts at 0 (zero) while the read pointer
812 * starts at zero with rollover bit set
813 */
814 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800815 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700816
Avinash Patile05dc3e2013-02-08 18:18:08 -0800817 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800818 MWIFIEX_MAX_EVT_BD;
819
Amitkumar Karward930fae2011-10-11 17:41:21 -0700820 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700821 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800822 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
823 card->evtbd_ring_size,
824 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700825 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700826 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800827 "allocate consistent memory (%d bytes) failed!\n",
828 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800829 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700830 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700831
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700832 dev_dbg(adapter->dev,
833 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
834 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
835 (u32)((u64)card->evtbd_ring_pbase >> 32),
836 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700837
Avinash Patil07324842013-02-08 18:18:07 -0800838 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700839}
840
841/*
842 * This function deletes Buffer descriptor ring for Events
843 */
844static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
845{
846 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800847 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700848
Avinash Patil07324842013-02-08 18:18:07 -0800849 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700850
Avinash Patilfc331462013-01-03 21:21:30 -0800851 if (card->evtbd_ring_vbase)
852 pci_free_consistent(card->dev, card->evtbd_ring_size,
853 card->evtbd_ring_vbase,
854 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700855 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800856 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700857 card->evtbd_ring_size = 0;
858 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800859 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700860
861 return 0;
862}
863
864/*
865 * This function allocates a buffer for CMDRSP
866 */
867static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
868{
869 struct pcie_service_card *card = adapter->card;
870 struct sk_buff *skb;
871
872 /* Allocate memory for receiving command response data */
873 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
874 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700875 dev_err(adapter->dev,
876 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700877 return -ENOMEM;
878 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700879 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800880 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
881 PCI_DMA_FROMDEVICE))
882 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700883
Avinash Patilfc331462013-01-03 21:21:30 -0800884 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700885
886 return 0;
887}
888
889/*
890 * This function deletes a buffer for CMDRSP
891 */
892static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
893{
894 struct pcie_service_card *card;
895
896 if (!adapter)
897 return 0;
898
899 card = adapter->card;
900
Avinash Patilfc331462013-01-03 21:21:30 -0800901 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800902 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
903 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700904 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800905 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700906
Avinash Patilfc331462013-01-03 21:21:30 -0800907 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800908 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
909 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800910 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700911 return 0;
912}
913
914/*
915 * This function allocates a buffer for sleep cookie
916 */
917static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
918{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700919 struct pcie_service_card *card = adapter->card;
920
Avinash Patilfc331462013-01-03 21:21:30 -0800921 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
922 &card->sleep_cookie_pbase);
923 if (!card->sleep_cookie_vbase) {
924 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700925 return -ENOMEM;
926 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700927 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800928 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700929
930 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800931 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700932
933 return 0;
934}
935
936/*
937 * This function deletes buffer for sleep cookie
938 */
939static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
940{
941 struct pcie_service_card *card;
942
943 if (!adapter)
944 return 0;
945
946 card = adapter->card;
947
Avinash Patilfc331462013-01-03 21:21:30 -0800948 if (card && card->sleep_cookie_vbase) {
949 pci_free_consistent(card->dev, sizeof(u32),
950 card->sleep_cookie_vbase,
951 card->sleep_cookie_pbase);
952 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700953 }
954
955 return 0;
956}
957
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800958/* This function flushes the TX buffer descriptor ring
959 * This function defined as handler is also called while cleaning TXRX
960 * during disconnect/ bss stop.
961 */
962static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
963{
964 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800965
Avinash Patil48f4d912013-02-20 21:12:58 -0800966 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800967 card->txbd_flush = 1;
968 /* write pointer already set at last send
969 * send dnld-rdy intr again, wait for completion.
970 */
971 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
972 CPU_INTR_DNLD_RDY)) {
973 dev_err(adapter->dev,
974 "failed to assert dnld-rdy interrupt.\n");
975 return -1;
976 }
977 }
978 return 0;
979}
980
Amitkumar Karward930fae2011-10-11 17:41:21 -0700981/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800982 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700983 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800984static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700985{
Avinash Patile7f767a2013-01-03 21:21:32 -0800986 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800987 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800988 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800989 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700990 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800991 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700992
993 if (!mwifiex_pcie_ok_to_access_hw(adapter))
994 mwifiex_pm_wakeup_card(adapter);
995
996 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800997 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700998 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800999 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001000 return -1;
1001 }
1002
Avinash Patile7f767a2013-01-03 21:21:32 -08001003 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
1004 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001005
Avinash Patilca8f2112013-02-08 18:18:09 -08001006 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001007 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001008 while (((card->txbd_rdptr & reg->tx_mask) !=
1009 (rdptr & reg->tx_mask)) ||
1010 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
1011 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -08001012 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
1013 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001014
1015 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -08001016
Avinash Patile7f767a2013-01-03 21:21:32 -08001017 if (skb) {
1018 dev_dbg(adapter->dev,
1019 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
1020 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -08001021 mwifiex_unmap_pci_memory(adapter, skb,
1022 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001023
1024 unmap_count++;
1025
1026 if (card->txbd_flush)
1027 mwifiex_write_data_complete(adapter, skb, 0,
1028 -1);
1029 else
1030 mwifiex_write_data_complete(adapter, skb, 0, 0);
1031 }
1032
1033 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001034
1035 if (reg->pfu_enabled) {
1036 desc2 = (void *)card->txbd_ring[wrdoneidx];
1037 memset(desc2, 0, sizeof(*desc2));
1038 } else {
1039 desc = card->txbd_ring[wrdoneidx];
1040 memset(desc, 0, sizeof(*desc));
1041 }
1042 switch (card->dev->device) {
1043 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1044 card->txbd_rdptr++;
1045 break;
1046 case PCIE_DEVICE_ID_MARVELL_88W8897:
1047 card->txbd_rdptr += reg->ring_tx_start_ptr;
1048 break;
1049 }
1050
Avinash Patile7f767a2013-01-03 21:21:32 -08001051
Avinash Patildd04e6a2013-02-08 18:18:06 -08001052 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001053 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001054 reg->tx_rollover_ind) ^
1055 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001056 }
1057
1058 if (unmap_count)
1059 adapter->data_sent = false;
1060
1061 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001062 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001063 card->txbd_flush = 0;
1064 else
1065 mwifiex_clean_pcie_ring_buf(adapter);
1066 }
1067
1068 return 0;
1069}
1070
1071/* This function sends data buffer to device. First 4 bytes of payload
1072 * are filled with payload length and payload type. Then this payload
1073 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1074 * Download ready interrupt to FW is deffered if Tx ring is not full and
1075 * additional payload can be accomodated.
1076 */
1077static int
1078mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1079 struct mwifiex_tx_param *tx_param)
1080{
1081 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001082 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001083 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001084 int ret;
1085 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001086 struct mwifiex_pcie_buf_desc *desc = NULL;
1087 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001088 __le16 *tmp;
1089
1090 if (!(skb->data && skb->len)) {
1091 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1092 __func__, skb->data, skb->len);
1093 return -1;
1094 }
1095
1096 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1097 mwifiex_pm_wakeup_card(adapter);
1098
Avinash Patilca8f2112013-02-08 18:18:09 -08001099 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001100 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1101 card->txbd_rdptr, card->txbd_wrptr);
1102 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001103 u8 *payload;
1104
1105 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001106 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001107 tmp = (__le16 *)&payload[0];
1108 *tmp = cpu_to_le16((u16)skb->len);
1109 tmp = (__le16 *)&payload[2];
1110 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001111
Aaron Durbindbccc922014-02-07 16:25:50 -08001112 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001113 PCI_DMA_TODEVICE))
1114 return -1;
1115
Avinash Patilca8f2112013-02-08 18:18:09 -08001116 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001117 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001118 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001119
Avinash Patilca8f2112013-02-08 18:18:09 -08001120 if (reg->pfu_enabled) {
1121 desc2 = (void *)card->txbd_ring[wrindx];
1122 desc2->paddr = buf_pa;
1123 desc2->len = (u16)skb->len;
1124 desc2->frag_len = (u16)skb->len;
1125 desc2->offset = 0;
1126 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1127 MWIFIEX_BD_FLAG_LAST_DESC;
1128 } else {
1129 desc = card->txbd_ring[wrindx];
1130 desc->paddr = buf_pa;
1131 desc->len = (u16)skb->len;
1132 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1133 MWIFIEX_BD_FLAG_LAST_DESC;
1134 }
1135
1136 switch (card->dev->device) {
1137 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1138 card->txbd_wrptr++;
1139 break;
1140 case PCIE_DEVICE_ID_MARVELL_88W8897:
1141 card->txbd_wrptr += reg->ring_tx_start_ptr;
1142 break;
1143 }
1144
1145 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001146 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001147 reg->tx_rollover_ind) ^
1148 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001149
Avinash Patilca8f2112013-02-08 18:18:09 -08001150 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001151 /* Write the TX ring write pointer in to reg->tx_wrptr */
1152 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001153 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001154 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001155 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001156 ret = -1;
1157 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001158 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001159 if ((mwifiex_pcie_txbd_not_full(card)) &&
1160 tx_param->next_pkt_len) {
1161 /* have more packets and TxBD still can hold more */
1162 dev_dbg(adapter->dev,
1163 "SEND DATA: delay dnld-rdy interrupt.\n");
1164 adapter->data_sent = false;
1165 } else {
1166 /* Send the TX ready interrupt */
1167 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1168 CPU_INTR_DNLD_RDY)) {
1169 dev_err(adapter->dev,
1170 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1171 ret = -1;
1172 goto done_unmap;
1173 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001174 }
1175 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001176 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001177 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001178 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001179 dev_dbg(adapter->dev,
1180 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001181 adapter->data_sent = true;
1182 /* Send the TX ready interrupt */
1183 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1184 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001185 dev_err(adapter->dev,
1186 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001187 return -EBUSY;
1188 }
1189
Avinash Patile7f767a2013-01-03 21:21:32 -08001190 return -EINPROGRESS;
1191done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001192 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001193 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001194 if (reg->pfu_enabled)
1195 memset(desc2, 0, sizeof(*desc2));
1196 else
1197 memset(desc, 0, sizeof(*desc));
1198
Avinash Patile7f767a2013-01-03 21:21:32 -08001199 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001200}
1201
1202/*
1203 * This function handles received buffer ring and
1204 * dispatches packets to upper
1205 */
1206static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1207{
1208 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001209 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001210 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001211 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001212 int ret = 0;
1213 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001214 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001215 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001216
Avinash Patile7f767a2013-01-03 21:21:32 -08001217 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1218 mwifiex_pm_wakeup_card(adapter);
1219
Amitkumar Karward930fae2011-10-11 17:41:21 -07001220 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001221 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001222 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001223 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001224 ret = -1;
1225 goto done;
1226 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001227 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001228
Avinash Patildd04e6a2013-02-08 18:18:06 -08001229 while (((wrptr & reg->rx_mask) !=
1230 (card->rxbd_rdptr & reg->rx_mask)) ||
1231 ((wrptr & reg->rx_rollover_ind) ==
1232 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001233 struct sk_buff *skb_data;
1234 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001235 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001236
Avinash Patildd04e6a2013-02-08 18:18:06 -08001237 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001238 skb_data = card->rx_buf_list[rd_index];
1239
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001240 /* If skb allocation was failed earlier for Rx packet,
1241 * rx_buf_list[rd_index] would have been left with a NULL.
1242 */
1243 if (!skb_data)
1244 return -ENOMEM;
1245
Aaron Durbindbccc922014-02-07 16:25:50 -08001246 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001247 card->rx_buf_list[rd_index] = NULL;
1248
Amitkumar Karward930fae2011-10-11 17:41:21 -07001249 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001250 * first 2 bytes for len, next 2 bytes is for type
1251 */
1252 pkt_len = *((__le16 *)skb_data->data);
1253 rx_len = le16_to_cpu(pkt_len);
1254 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001255 dev_dbg(adapter->dev,
1256 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1257 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001258 skb_pull(skb_data, INTF_HEADER_LEN);
1259 mwifiex_handle_rx_packet(adapter, skb_data);
1260
1261 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001262 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001263 dev_err(adapter->dev,
1264 "Unable to allocate skb.\n");
1265 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001266 }
1267
Avinash Patile7f767a2013-01-03 21:21:32 -08001268 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1269 MWIFIEX_RX_DATA_BUF_SIZE,
1270 PCI_DMA_FROMDEVICE))
1271 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001272
Aaron Durbindbccc922014-02-07 16:25:50 -08001273 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001274
1275 dev_dbg(adapter->dev,
1276 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1277 skb_tmp, rd_index);
1278 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001279
1280 if (reg->pfu_enabled) {
1281 desc2 = (void *)card->rxbd_ring[rd_index];
1282 desc2->paddr = buf_pa;
1283 desc2->len = skb_tmp->len;
1284 desc2->frag_len = skb_tmp->len;
1285 desc2->offset = 0;
1286 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1287 } else {
1288 desc = card->rxbd_ring[rd_index];
1289 desc->paddr = buf_pa;
1290 desc->len = skb_tmp->len;
1291 desc->flags = 0;
1292 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001293
Avinash Patildd04e6a2013-02-08 18:18:06 -08001294 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001295 MWIFIEX_MAX_TXRX_BD) {
1296 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001297 reg->rx_rollover_ind) ^
1298 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001299 }
1300 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001301 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001302
Avinash Patilca8f2112013-02-08 18:18:09 -08001303 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001304 /* Write the RX ring read pointer in to reg->rx_rdptr */
1305 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001306 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001307 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001308 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001309 ret = -1;
1310 goto done;
1311 }
1312
1313 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001314 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001315 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001316 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001317 ret = -1;
1318 goto done;
1319 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001320 dev_dbg(adapter->dev,
1321 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001322 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001323 }
1324
1325done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001326 return ret;
1327}
1328
1329/*
1330 * This function downloads the boot command to device
1331 */
1332static int
1333mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1334{
Avinash Patilfc331462013-01-03 21:21:30 -08001335 dma_addr_t buf_pa;
1336 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001337 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001338
Avinash Patilfc331462013-01-03 21:21:30 -08001339 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001340 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001341 "Invalid parameter in %s <%p. len %d>\n",
1342 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001343 return -1;
1344 }
1345
Avinash Patilfc331462013-01-03 21:21:30 -08001346 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1347 return -1;
1348
Aaron Durbindbccc922014-02-07 16:25:50 -08001349 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001350
Avinash Patildd04e6a2013-02-08 18:18:06 -08001351 /* Write the lower 32bits of the physical address to low command
1352 * address scratch register
1353 */
1354 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001355 dev_err(adapter->dev,
1356 "%s: failed to write download command to boot code.\n",
1357 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001358 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001359 return -1;
1360 }
1361
Avinash Patildd04e6a2013-02-08 18:18:06 -08001362 /* Write the upper 32bits of the physical address to high command
1363 * address scratch register
1364 */
1365 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001366 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001367 dev_err(adapter->dev,
1368 "%s: failed to write download command to boot code.\n",
1369 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001370 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001371 return -1;
1372 }
1373
Avinash Patildd04e6a2013-02-08 18:18:06 -08001374 /* Write the command length to cmd_size scratch register */
1375 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001376 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001377 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001378 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001379 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001380 return -1;
1381 }
1382
1383 /* Ring the door bell */
1384 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1385 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001386 dev_err(adapter->dev,
1387 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001388 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001389 return -1;
1390 }
1391
1392 return 0;
1393}
1394
Avinash Patilc6d1d872013-01-03 21:21:29 -08001395/* This function init rx port in firmware which in turn enables to receive data
1396 * from device before transmitting any packet.
1397 */
1398static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1399{
1400 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001401 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001402 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001403
Avinash Patildd04e6a2013-02-08 18:18:06 -08001404 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001405 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1406 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001407 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001408 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001409 return -1;
1410 }
1411 return 0;
1412}
1413
1414/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001415 */
1416static int
1417mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1418{
1419 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001420 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001421 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001422 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1423 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001424
1425 if (!(skb->data && skb->len)) {
1426 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001427 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001428 return -1;
1429 }
1430
1431 /* Make sure a command response buffer is available */
1432 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001433 dev_err(adapter->dev,
1434 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001435 return -EBUSY;
1436 }
1437
Avinash Patilfc331462013-01-03 21:21:30 -08001438 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1439 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001440
1441 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001442
1443 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1444 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1445
1446 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1447 return -1;
1448
1449 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001450
1451 /* To send a command, the driver will:
1452 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001453 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001454 2. Ring the door bell (i.e. set the door bell interrupt)
1455
1456 In response to door bell interrupt, the firmware will perform
1457 the DMA of the command packet (first header to obtain the total
1458 length and then rest of the command).
1459 */
1460
1461 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001462 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001463 /* Write the lower 32bits of the cmdrsp buffer physical
1464 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001465 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001466 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001467 dev_err(adapter->dev,
1468 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001469 ret = -1;
1470 goto done;
1471 }
1472 /* Write the upper 32bits of the cmdrsp buffer physical
1473 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001474 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001475 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001476 dev_err(adapter->dev,
1477 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001478 ret = -1;
1479 goto done;
1480 }
1481 }
1482
Aaron Durbindbccc922014-02-07 16:25:50 -08001483 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001484 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1485 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1486 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001487 dev_err(adapter->dev,
1488 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001489 ret = -1;
1490 goto done;
1491 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001492 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1493 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001494 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001495 dev_err(adapter->dev,
1496 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001497 ret = -1;
1498 goto done;
1499 }
1500
Avinash Patildd04e6a2013-02-08 18:18:06 -08001501 /* Write the command length to reg->cmd_size */
1502 if (mwifiex_write_reg(adapter, reg->cmd_size,
1503 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001504 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001505 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001506 ret = -1;
1507 goto done;
1508 }
1509
1510 /* Ring the door bell */
1511 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1512 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001513 dev_err(adapter->dev,
1514 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001515 ret = -1;
1516 goto done;
1517 }
1518
1519done:
1520 if (ret)
1521 adapter->cmd_sent = false;
1522
1523 return 0;
1524}
1525
1526/*
1527 * This function handles command complete interrupt
1528 */
1529static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1530{
1531 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001532 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001533 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001534 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001535 u16 rx_len;
1536 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001537
1538 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1539
Aaron Durbindbccc922014-02-07 16:25:50 -08001540 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001541
Aaron Durbin189b3292014-02-07 16:25:51 -08001542 /* Unmap the command as a response has been received. */
1543 if (card->cmd_buf) {
1544 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1545 PCI_DMA_TODEVICE);
1546 card->cmd_buf = NULL;
1547 }
1548
Avinash Patilfc331462013-01-03 21:21:30 -08001549 pkt_len = *((__le16 *)skb->data);
1550 rx_len = le16_to_cpu(pkt_len);
1551 skb_trim(skb, rx_len);
1552 skb_pull(skb, INTF_HEADER_LEN);
1553
Amitkumar Karward930fae2011-10-11 17:41:21 -07001554 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001555 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001556 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1557 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001558 mwifiex_pcie_enable_host_int(adapter);
1559 if (mwifiex_write_reg(adapter,
1560 PCIE_CPU_INT_EVENT,
1561 CPU_INTR_SLEEP_CFM_DONE)) {
1562 dev_warn(adapter->dev,
1563 "Write register failed\n");
1564 return -1;
1565 }
Avinash Patilc4bc9802014-03-18 22:19:17 -07001566 mwifiex_delay_for_sleep_cookie(adapter,
1567 MWIFIEX_MAX_DELAY_COUNT);
Avinash Patil52301a82013-02-12 14:38:32 -08001568 while (reg->sleep_cookie && (count++ < 10) &&
1569 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001570 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001571 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001572 dev_err(adapter->dev,
1573 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001574 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001575 memcpy(adapter->upld_buf, skb->data,
1576 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001577 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001578 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1579 PCI_DMA_FROMDEVICE))
1580 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001581 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001582 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001583 adapter->cmd_resp_received = true;
1584 /* Take the pointer and set it to CMD node and will
1585 return in the response complete callback */
1586 card->cmdrsp_buf = NULL;
1587
1588 /* Clear the cmd-rsp buffer address in scratch registers. This
1589 will prevent firmware from writing to the same response
1590 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001591 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001592 dev_err(adapter->dev,
1593 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001594 return -1;
1595 }
1596 /* Write the upper 32bits of the cmdrsp buffer physical
1597 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001598 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001599 dev_err(adapter->dev,
1600 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001601 return -1;
1602 }
1603 }
1604
1605 return 0;
1606}
1607
1608/*
1609 * Command Response processing complete handler
1610 */
1611static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1612 struct sk_buff *skb)
1613{
1614 struct pcie_service_card *card = adapter->card;
1615
1616 if (skb) {
1617 card->cmdrsp_buf = skb;
1618 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001619 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1620 PCI_DMA_FROMDEVICE))
1621 return -1;
1622 }
1623
Amitkumar Karward930fae2011-10-11 17:41:21 -07001624 return 0;
1625}
1626
1627/*
1628 * This function handles firmware event ready interrupt
1629 */
1630static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1631{
1632 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001633 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001634 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1635 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001636 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001637
1638 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1639 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001640
1641 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001642 dev_dbg(adapter->dev, "info: Event being processed, "
1643 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001644 return 0;
1645 }
1646
1647 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1648 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1649 return -1;
1650 }
1651
1652 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001653 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001654 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001655 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001656 return -1;
1657 }
1658
1659 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001660 card->evtbd_rdptr, wrptr);
1661 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1662 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001663 ((wrptr & reg->evt_rollover_ind) ==
1664 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001665 struct sk_buff *skb_cmd;
1666 __le16 data_len = 0;
1667 u16 evt_len;
1668
1669 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1670 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001671 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001672
Amitkumar Karward930fae2011-10-11 17:41:21 -07001673 /* Take the pointer and set it to event pointer in adapter
1674 and will return back after event handling callback */
1675 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001676 desc = card->evtbd_ring[rdptr];
1677 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001678
1679 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1680 adapter->event_cause = event;
1681 /* The first 4bytes will be the event transfer header
1682 len is 2 bytes followed by type which is 2 bytes */
1683 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1684 evt_len = le16_to_cpu(data_len);
1685
1686 skb_pull(skb_cmd, INTF_HEADER_LEN);
1687 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1688
1689 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1690 memcpy(adapter->event_body, skb_cmd->data +
1691 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1692 MWIFIEX_EVENT_HEADER_LEN);
1693
1694 adapter->event_received = true;
1695 adapter->event_skb = skb_cmd;
1696
1697 /* Do not update the event read pointer here, wait till the
1698 buffer is released. This is just to make things simpler,
1699 we need to find a better method of managing these buffers.
1700 */
1701 }
1702
1703 return 0;
1704}
1705
1706/*
1707 * Event processing complete handler
1708 */
1709static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1710 struct sk_buff *skb)
1711{
1712 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001713 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001714 int ret = 0;
1715 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1716 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001717 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001718
1719 if (!skb)
1720 return 0;
1721
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001722 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001723 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001724 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001725 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001726 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001727
1728 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001729 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001730 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001731 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001732 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001733 }
1734
1735 if (!card->evt_buf_list[rdptr]) {
1736 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001737 if (mwifiex_map_pci_memory(adapter, skb,
1738 MAX_EVENT_SIZE,
1739 PCI_DMA_FROMDEVICE))
1740 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001741 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001742 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001743 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001744 desc->len = (u16)skb->len;
1745 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001746 skb = NULL;
1747 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001748 dev_dbg(adapter->dev,
1749 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1750 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001751 }
1752
1753 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1754 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001755 reg->evt_rollover_ind) ^
1756 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001757 }
1758
1759 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001760 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001761
Avinash Patildd04e6a2013-02-08 18:18:06 -08001762 /* Write the event ring read pointer in to reg->evt_rdptr */
1763 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1764 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001765 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001766 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001767 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001768 }
1769
Amitkumar Karward930fae2011-10-11 17:41:21 -07001770 dev_dbg(adapter->dev, "info: Check Events Again\n");
1771 ret = mwifiex_pcie_process_event_ready(adapter);
1772
1773 return ret;
1774}
1775
1776/*
1777 * This function downloads the firmware to the card.
1778 *
1779 * Firmware is downloaded to the card in blocks. Every block download
1780 * is tested for CRC errors, and retried a number of times before
1781 * returning failure.
1782 */
1783static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1784 struct mwifiex_fw_image *fw)
1785{
1786 int ret;
1787 u8 *firmware = fw->fw_buf;
1788 u32 firmware_len = fw->fw_len;
1789 u32 offset = 0;
1790 struct sk_buff *skb;
1791 u32 txlen, tx_blocks = 0, tries, len;
1792 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001793 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001794 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001795
1796 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001797 dev_err(adapter->dev,
1798 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001799 return -1;
1800 }
1801
1802 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001803 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001804
1805 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001806 dev_err(adapter->dev,
1807 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001808 return -1;
1809 }
1810
1811 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1812 if (!skb) {
1813 ret = -ENOMEM;
1814 goto done;
1815 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001816
1817 /* Perform firmware data transfer */
1818 do {
1819 u32 ireg_intr = 0;
1820
1821 /* More data? */
1822 if (offset >= firmware_len)
1823 break;
1824
1825 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001826 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001827 &len);
1828 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001829 dev_warn(adapter->dev,
1830 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001831 goto done;
1832 }
1833 if (len)
1834 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001835 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001836 }
1837
1838 if (!len) {
1839 break;
1840 } else if (len > MWIFIEX_UPLD_SIZE) {
1841 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001842 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001843 ret = -1;
1844 goto done;
1845 }
1846
1847 txlen = len;
1848
1849 if (len & BIT(0)) {
1850 block_retry_cnt++;
1851 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1852 pr_err("FW download failure @ %d, over max "
1853 "retry count\n", offset);
1854 ret = -1;
1855 goto done;
1856 }
1857 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001858 "helper: len = 0x%04X, txlen = %d\n",
1859 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001860 len &= ~BIT(0);
1861 /* Setting this to 0 to resend from same offset */
1862 txlen = 0;
1863 } else {
1864 block_retry_cnt = 0;
1865 /* Set blocksize to transfer - checking for
1866 last block */
1867 if (firmware_len - offset < txlen)
1868 txlen = firmware_len - offset;
1869
1870 dev_dbg(adapter->dev, ".");
1871
Avinash Patildd04e6a2013-02-08 18:18:06 -08001872 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1873 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001874
1875 /* Copy payload to buffer */
1876 memmove(skb->data, &firmware[offset], txlen);
1877 }
1878
1879 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001880 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001881
1882 /* Send the boot command to device */
1883 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001884 dev_err(adapter->dev,
1885 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001886 ret = -1;
1887 goto done;
1888 }
Avinash Patilfc331462013-01-03 21:21:30 -08001889
Amitkumar Karward930fae2011-10-11 17:41:21 -07001890 /* Wait for the command done interrupt */
1891 do {
1892 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1893 &ireg_intr)) {
1894 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001895 "interrupt status during fw dnld.\n",
1896 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001897 mwifiex_unmap_pci_memory(adapter, skb,
1898 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001899 ret = -1;
1900 goto done;
1901 }
1902 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1903 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001904
Aaron Durbindbccc922014-02-07 16:25:50 -08001905 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001906
Amitkumar Karward930fae2011-10-11 17:41:21 -07001907 offset += txlen;
1908 } while (true);
1909
1910 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001911 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001912
1913 ret = 0;
1914
1915done:
1916 dev_kfree_skb_any(skb);
1917 return ret;
1918}
1919
1920/*
1921 * This function checks the firmware status in card.
1922 *
1923 * The winner interface is also determined by this function.
1924 */
1925static int
1926mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1927{
1928 int ret = 0;
1929 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001930 struct pcie_service_card *card = adapter->card;
1931 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001932 u32 tries;
1933
1934 /* Mask spurios interrupts */
1935 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001936 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001937 dev_warn(adapter->dev, "Write register failed\n");
1938 return -1;
1939 }
1940
1941 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001942 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1943 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001944 dev_err(adapter->dev,
1945 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001946 return -1;
1947 }
1948
1949 /* Wait for firmware initialization event */
1950 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001951 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001952 &firmware_stat))
1953 ret = -1;
1954 else
1955 ret = 0;
1956 if (ret)
1957 continue;
1958 if (firmware_stat == FIRMWARE_READY_PCIE) {
1959 ret = 0;
1960 break;
1961 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07001962 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001963 ret = -1;
1964 }
1965 }
1966
1967 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001968 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001969 &winner_status))
1970 ret = -1;
1971 else if (!winner_status) {
1972 dev_err(adapter->dev, "PCI-E is the winner\n");
1973 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001974 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001975 dev_err(adapter->dev,
1976 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1977 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001978 }
1979 }
1980
1981 return ret;
1982}
1983
1984/*
1985 * This function reads the interrupt status from card.
1986 */
1987static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1988{
1989 u32 pcie_ireg;
1990 unsigned long flags;
1991
1992 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1993 return;
1994
1995 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1996 dev_warn(adapter->dev, "Read register failed\n");
1997 return;
1998 }
1999
2000 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2001
2002 mwifiex_pcie_disable_host_int(adapter);
2003
2004 /* Clear the pending interrupts */
2005 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2006 ~pcie_ireg)) {
2007 dev_warn(adapter->dev, "Write register failed\n");
2008 return;
2009 }
2010 spin_lock_irqsave(&adapter->int_lock, flags);
2011 adapter->int_status |= pcie_ireg;
2012 spin_unlock_irqrestore(&adapter->int_lock, flags);
2013
Amitkumar Karwar1c975602014-02-18 15:41:56 -08002014 if (!adapter->pps_uapsd_mode &&
2015 adapter->ps_state == PS_STATE_SLEEP &&
2016 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002017 /* Potentially for PCIe we could get other
2018 * interrupts like shared. Don't change power
2019 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002020 adapter->ps_state = PS_STATE_AWAKE;
2021 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002022 }
2023 }
2024}
2025
2026/*
2027 * Interrupt handler for PCIe root port
2028 *
2029 * This function reads the interrupt status from firmware and assigns
2030 * the main process in workqueue which will handle the interrupt.
2031 */
2032static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2033{
2034 struct pci_dev *pdev = (struct pci_dev *)context;
2035 struct pcie_service_card *card;
2036 struct mwifiex_adapter *adapter;
2037
2038 if (!pdev) {
2039 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2040 goto exit;
2041 }
2042
Jingoo Hanb2a31202013-09-09 14:26:51 +09002043 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002044 if (!card || !card->adapter) {
2045 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002046 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002047 goto exit;
2048 }
2049 adapter = card->adapter;
2050
2051 if (adapter->surprise_removed)
2052 goto exit;
2053
2054 mwifiex_interrupt_status(adapter);
2055 queue_work(adapter->workqueue, &adapter->main_work);
2056
2057exit:
2058 return IRQ_HANDLED;
2059}
2060
2061/*
2062 * This function checks the current interrupt status.
2063 *
2064 * The following interrupts are checked and handled by this function -
2065 * - Data sent
2066 * - Command sent
2067 * - Command received
2068 * - Packets received
2069 * - Events received
2070 *
2071 * In case of Rx packets received, the packets are uploaded from card to
2072 * host and processed accordingly.
2073 */
2074static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2075{
2076 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002077 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002078 unsigned long flags;
2079
2080 spin_lock_irqsave(&adapter->int_lock, flags);
2081 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002082 pcie_ireg = adapter->int_status;
2083 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002084 spin_unlock_irqrestore(&adapter->int_lock, flags);
2085
Avinash Patil659c4782013-01-03 21:21:28 -08002086 while (pcie_ireg & HOST_INTR_MASK) {
2087 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2088 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002089 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2090 ret = mwifiex_pcie_send_data_complete(adapter);
2091 if (ret)
2092 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002093 }
Avinash Patil659c4782013-01-03 21:21:28 -08002094 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2095 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002096 dev_dbg(adapter->dev, "info: Rx DATA\n");
2097 ret = mwifiex_pcie_process_recv_data(adapter);
2098 if (ret)
2099 return ret;
2100 }
Avinash Patil659c4782013-01-03 21:21:28 -08002101 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2102 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002103 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2104 ret = mwifiex_pcie_process_event_ready(adapter);
2105 if (ret)
2106 return ret;
2107 }
2108
Avinash Patil659c4782013-01-03 21:21:28 -08002109 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2110 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002111 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002112 dev_dbg(adapter->dev,
2113 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002114 adapter->cmd_sent = false;
2115 }
2116 /* Handle command response */
2117 ret = mwifiex_pcie_process_cmd_complete(adapter);
2118 if (ret)
2119 return ret;
2120 }
2121
2122 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2123 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2124 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002125 dev_warn(adapter->dev,
2126 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002127 return -1;
2128 }
2129
2130 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2131 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002132 PCIE_HOST_INT_STATUS,
2133 ~pcie_ireg)) {
2134 dev_warn(adapter->dev,
2135 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002136 return -1;
2137 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002138 }
2139
2140 }
2141 }
2142 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002143 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002144 if (adapter->ps_state != PS_STATE_SLEEP)
2145 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002146
2147 return 0;
2148}
2149
2150/*
2151 * This function downloads data from driver to card.
2152 *
2153 * Both commands and data packets are transferred to the card by this
2154 * function.
2155 *
2156 * This function adds the PCIE specific header to the front of the buffer
2157 * before transferring. The header contains the length of the packet and
2158 * the type. The firmware handles the packets based upon this set type.
2159 */
2160static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2161 struct sk_buff *skb,
2162 struct mwifiex_tx_param *tx_param)
2163{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002164 if (!skb) {
2165 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002166 return -1;
2167 }
2168
2169 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002170 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002171 else if (type == MWIFIEX_TYPE_CMD)
2172 return mwifiex_pcie_send_cmd(adapter, skb);
2173
2174 return 0;
2175}
2176
2177/*
2178 * This function initializes the PCI-E host memory space, WCB rings, etc.
2179 *
2180 * The following initializations steps are followed -
2181 * - Allocate TXBD ring buffers
2182 * - Allocate RXBD ring buffers
2183 * - Allocate event BD ring buffers
2184 * - Allocate command response ring buffer
2185 * - Allocate sleep cookie buffer
2186 */
2187static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2188{
2189 struct pcie_service_card *card = adapter->card;
2190 int ret;
2191 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002192 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002193
2194 pci_set_drvdata(pdev, card);
2195
2196 ret = pci_enable_device(pdev);
2197 if (ret)
2198 goto err_enable_dev;
2199
2200 pci_set_master(pdev);
2201
2202 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2203 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2204 if (ret) {
2205 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2206 goto err_set_dma_mask;
2207 }
2208
2209 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2210 if (ret) {
2211 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2212 goto err_set_dma_mask;
2213 }
2214
2215 ret = pci_request_region(pdev, 0, DRV_NAME);
2216 if (ret) {
2217 dev_err(adapter->dev, "req_reg(0) error\n");
2218 goto err_req_region0;
2219 }
2220 card->pci_mmap = pci_iomap(pdev, 0, 0);
2221 if (!card->pci_mmap) {
2222 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002223 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002224 goto err_iomap0;
2225 }
2226 ret = pci_request_region(pdev, 2, DRV_NAME);
2227 if (ret) {
2228 dev_err(adapter->dev, "req_reg(2) error\n");
2229 goto err_req_region2;
2230 }
2231 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2232 if (!card->pci_mmap1) {
2233 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002234 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002235 goto err_iomap2;
2236 }
2237
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002238 dev_dbg(adapter->dev,
2239 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2240 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002241
2242 card->cmdrsp_buf = NULL;
2243 ret = mwifiex_pcie_create_txbd_ring(adapter);
2244 if (ret)
2245 goto err_cre_txbd;
2246 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2247 if (ret)
2248 goto err_cre_rxbd;
2249 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2250 if (ret)
2251 goto err_cre_evtbd;
2252 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2253 if (ret)
2254 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002255 if (reg->sleep_cookie) {
2256 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2257 if (ret)
2258 goto err_alloc_cookie;
2259 } else {
2260 card->sleep_cookie_vbase = NULL;
2261 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002262 return ret;
2263
2264err_alloc_cookie:
2265 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2266err_alloc_cmdbuf:
2267 mwifiex_pcie_delete_evtbd_ring(adapter);
2268err_cre_evtbd:
2269 mwifiex_pcie_delete_rxbd_ring(adapter);
2270err_cre_rxbd:
2271 mwifiex_pcie_delete_txbd_ring(adapter);
2272err_cre_txbd:
2273 pci_iounmap(pdev, card->pci_mmap1);
2274err_iomap2:
2275 pci_release_region(pdev, 2);
2276err_req_region2:
2277 pci_iounmap(pdev, card->pci_mmap);
2278err_iomap0:
2279 pci_release_region(pdev, 0);
2280err_req_region0:
2281err_set_dma_mask:
2282 pci_disable_device(pdev);
2283err_enable_dev:
2284 pci_set_drvdata(pdev, NULL);
2285 return ret;
2286}
2287
2288/*
2289 * This function cleans up the allocated card buffers.
2290 *
2291 * The following are freed by this function -
2292 * - TXBD ring buffers
2293 * - RXBD ring buffers
2294 * - Event BD ring buffers
2295 * - Command response ring buffer
2296 * - Sleep cookie buffer
2297 */
2298static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2299{
2300 struct pcie_service_card *card = adapter->card;
2301 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002302 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002303
Amitkumar Karward930fae2011-10-11 17:41:21 -07002304 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002305 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002306 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002307 dev_err(adapter->dev,
2308 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002309 }
2310
2311 if (pdev) {
2312 pci_iounmap(pdev, card->pci_mmap);
2313 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002314 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002315 pci_release_region(pdev, 2);
2316 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002317 pci_set_drvdata(pdev, NULL);
2318 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002319 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002320}
2321
2322/*
2323 * This function registers the PCIE device.
2324 *
2325 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2326 */
2327static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2328{
2329 int ret;
2330 struct pcie_service_card *card = adapter->card;
2331 struct pci_dev *pdev = card->dev;
2332
2333 /* save adapter pointer in card */
2334 card->adapter = adapter;
2335
2336 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2337 "MRVL_PCIE", pdev);
2338 if (ret) {
2339 pr_err("request_irq failed: ret=%d\n", ret);
2340 adapter->card = NULL;
2341 return -1;
2342 }
2343
2344 adapter->dev = &pdev->dev;
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002345 adapter->tx_buf_size = card->pcie.tx_buf_size;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002346 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002347
2348 return 0;
2349}
2350
2351/*
2352 * This function unregisters the PCIE device.
2353 *
2354 * The PCIE IRQ is released, the function is disabled and driver
2355 * data is set to null.
2356 */
2357static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2358{
2359 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002360 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002361
2362 if (card) {
2363 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2364 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002365
Avinash Patil52301a82013-02-12 14:38:32 -08002366 reg = card->pcie.reg;
2367 if (reg->sleep_cookie)
2368 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2369
Avinash Patilfc331462013-01-03 21:21:30 -08002370 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2371 mwifiex_pcie_delete_evtbd_ring(adapter);
2372 mwifiex_pcie_delete_rxbd_ring(adapter);
2373 mwifiex_pcie_delete_txbd_ring(adapter);
2374 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002375 }
2376}
2377
2378static struct mwifiex_if_ops pcie_ops = {
2379 .init_if = mwifiex_pcie_init,
2380 .cleanup_if = mwifiex_pcie_cleanup,
2381 .check_fw_status = mwifiex_check_fw_status,
2382 .prog_fw = mwifiex_prog_fw_w_helper,
2383 .register_dev = mwifiex_register_dev,
2384 .unregister_dev = mwifiex_unregister_dev,
2385 .enable_int = mwifiex_pcie_enable_host_int,
2386 .process_int_status = mwifiex_process_int_status,
2387 .host_to_card = mwifiex_pcie_host_to_card,
2388 .wakeup = mwifiex_pm_wakeup_card,
2389 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2390
2391 /* PCIE specific */
2392 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2393 .event_complete = mwifiex_pcie_event_complete,
2394 .update_mp_end_port = NULL,
2395 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002396 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002397 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002398};
2399
2400/*
2401 * This function initializes the PCIE driver module.
2402 *
2403 * This initiates the semaphore and registers the device with
2404 * PCIE bus.
2405 */
2406static int mwifiex_pcie_init_module(void)
2407{
2408 int ret;
2409
Avinash Patilca8f2112013-02-08 18:18:09 -08002410 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002411
2412 sema_init(&add_remove_card_sem, 1);
2413
2414 /* Clear the flag in case user removes the card. */
2415 user_rmmod = 0;
2416
2417 ret = pci_register_driver(&mwifiex_pcie);
2418 if (ret)
2419 pr_err("Driver register failed!\n");
2420 else
2421 pr_debug("info: Driver registered successfully!\n");
2422
2423 return ret;
2424}
2425
2426/*
2427 * This function cleans up the PCIE driver.
2428 *
2429 * The following major steps are followed for cleanup -
2430 * - Resume the device if its suspended
2431 * - Disconnect the device if connected
2432 * - Shutdown the firmware
2433 * - Unregister the device from PCIE bus.
2434 */
2435static void mwifiex_pcie_cleanup_module(void)
2436{
2437 if (!down_interruptible(&add_remove_card_sem))
2438 up(&add_remove_card_sem);
2439
2440 /* Set the flag as user is removing this module. */
2441 user_rmmod = 1;
2442
2443 pci_unregister_driver(&mwifiex_pcie);
2444}
2445
2446module_init(mwifiex_pcie_init_module);
2447module_exit(mwifiex_pcie_cleanup_module);
2448
2449MODULE_AUTHOR("Marvell International Ltd.");
2450MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2451MODULE_VERSION(PCIE_VERSION);
2452MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002453MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2454MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);