blob: 9f1683b5f28f8e7c385751c8a34b239b2c2ff903 [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
330/* This function wakes up the card by reading fw_status register. */
331static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
332{
333 u32 fw_status;
334 struct pcie_service_card *card = adapter->card;
335 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
336
Amitkumar Karward930fae2011-10-11 17:41:21 -0700337 dev_dbg(adapter->dev, "event: Wakeup device...\n");
338
Avinash Patilc0880a22013-03-22 21:49:07 -0700339 if (reg->sleep_cookie)
340 mwifiex_pcie_dev_wakeup_delay(adapter);
341
342 /* Reading fw_status register will wakeup device */
343 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
344 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700345 return -1;
346 }
347
Avinash Patilc0880a22013-03-22 21:49:07 -0700348 if (reg->sleep_cookie) {
349 mwifiex_pcie_dev_wakeup_delay(adapter);
350 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
351 adapter->ps_state = PS_STATE_AWAKE;
352 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700353
354 return 0;
355}
356
357/*
358 * This function is called after the card has woken up.
359 *
360 * The card configuration register is reset.
361 */
362static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
363{
364 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
365
366 return 0;
367}
368
369/*
370 * This function disables the host interrupt.
371 *
372 * The host interrupt mask is read, the disable bit is reset and
373 * written back to the card host interrupt mask register.
374 */
375static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
376{
377 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
378 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
379 0x00000000)) {
380 dev_warn(adapter->dev, "Disable host interrupt failed\n");
381 return -1;
382 }
383 }
384
385 return 0;
386}
387
388/*
389 * This function enables the host interrupt.
390 *
391 * The host interrupt enable mask is written to the card
392 * host interrupt mask register.
393 */
394static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
395{
396 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
397 /* Simply write the mask to the register */
398 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
399 HOST_INTR_MASK)) {
400 dev_warn(adapter->dev, "Enable host interrupt failed\n");
401 return -1;
402 }
403 }
404
405 return 0;
406}
407
408/*
Avinash Patil07324842013-02-08 18:18:07 -0800409 * This function initializes TX buffer ring descriptors
410 */
411static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
412{
413 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800414 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800415 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800416 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800417 int i;
418
419 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
420 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800421 if (reg->pfu_enabled) {
422 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
423 (sizeof(*desc2) * i);
424 desc2 = card->txbd_ring[i];
425 memset(desc2, 0, sizeof(*desc2));
426 } else {
427 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
428 (sizeof(*desc) * i);
429 desc = card->txbd_ring[i];
430 memset(desc, 0, sizeof(*desc));
431 }
Avinash Patil07324842013-02-08 18:18:07 -0800432 }
433
434 return 0;
435}
436
437/* This function initializes RX buffer ring descriptors. Each SKB is allocated
438 * here and after mapping PCI memory, its physical address is assigned to
439 * PCIE Rx buffer descriptor's physical address.
440 */
441static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
442{
443 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800444 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800445 struct sk_buff *skb;
446 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800447 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800448 dma_addr_t buf_pa;
449 int i;
450
451 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
452 /* Allocate skb here so that firmware can DMA data from it */
453 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
454 if (!skb) {
455 dev_err(adapter->dev,
456 "Unable to allocate skb for RX ring.\n");
457 kfree(card->rxbd_ring_vbase);
458 return -ENOMEM;
459 }
460
461 if (mwifiex_map_pci_memory(adapter, skb,
462 MWIFIEX_RX_DATA_BUF_SIZE,
463 PCI_DMA_FROMDEVICE))
464 return -1;
465
Aaron Durbindbccc922014-02-07 16:25:50 -0800466 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800467
468 dev_dbg(adapter->dev,
469 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
470 skb, skb->len, skb->data, (u32)buf_pa,
471 (u32)((u64)buf_pa >> 32));
472
473 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800474 if (reg->pfu_enabled) {
475 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
476 (sizeof(*desc2) * i);
477 desc2 = card->rxbd_ring[i];
478 desc2->paddr = buf_pa;
479 desc2->len = (u16)skb->len;
480 desc2->frag_len = (u16)skb->len;
481 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
482 desc2->offset = 0;
483 } else {
484 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
485 (sizeof(*desc) * i));
486 desc = card->rxbd_ring[i];
487 desc->paddr = buf_pa;
488 desc->len = (u16)skb->len;
489 desc->flags = 0;
490 }
Avinash Patil07324842013-02-08 18:18:07 -0800491 }
492
493 return 0;
494}
495
496/* This function initializes event buffer ring descriptors. Each SKB is
497 * allocated here and after mapping PCI memory, its physical address is assigned
498 * to PCIE Rx buffer descriptor's physical address
499 */
500static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
501{
502 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800503 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800504 struct sk_buff *skb;
505 dma_addr_t buf_pa;
506 int i;
507
508 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
509 /* Allocate skb here so that firmware can DMA data from it */
510 skb = dev_alloc_skb(MAX_EVENT_SIZE);
511 if (!skb) {
512 dev_err(adapter->dev,
513 "Unable to allocate skb for EVENT buf.\n");
514 kfree(card->evtbd_ring_vbase);
515 return -ENOMEM;
516 }
517 skb_put(skb, MAX_EVENT_SIZE);
518
519 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
520 PCI_DMA_FROMDEVICE))
521 return -1;
522
Aaron Durbindbccc922014-02-07 16:25:50 -0800523 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800524
525 dev_dbg(adapter->dev,
526 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
527 skb, skb->len, skb->data, (u32)buf_pa,
528 (u32)((u64)buf_pa >> 32));
529
530 card->evt_buf_list[i] = skb;
531 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
532 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800533 desc = card->evtbd_ring[i];
534 desc->paddr = buf_pa;
535 desc->len = (u16)skb->len;
536 desc->flags = 0;
537 }
538
539 return 0;
540}
541
542/* This function cleans up TX buffer rings. If any of the buffer list has valid
543 * SKB address, associated SKB is freed.
544 */
545static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
546{
547 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800548 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800549 struct sk_buff *skb;
550 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800551 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800552 int i;
553
554 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800555 if (reg->pfu_enabled) {
556 desc2 = card->txbd_ring[i];
557 if (card->tx_buf_list[i]) {
558 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800559 mwifiex_unmap_pci_memory(adapter, skb,
560 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800561 dev_kfree_skb_any(skb);
562 }
563 memset(desc2, 0, sizeof(*desc2));
564 } else {
565 desc = card->txbd_ring[i];
566 if (card->tx_buf_list[i]) {
567 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800568 mwifiex_unmap_pci_memory(adapter, skb,
569 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800570 dev_kfree_skb_any(skb);
571 }
572 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800573 }
574 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800575 }
576
577 return;
578}
579
580/* This function cleans up RX buffer rings. If any of the buffer list has valid
581 * SKB address, associated SKB is freed.
582 */
583static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
584{
585 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800586 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800587 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800588 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800589 struct sk_buff *skb;
590 int i;
591
592 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800593 if (reg->pfu_enabled) {
594 desc2 = card->rxbd_ring[i];
595 if (card->rx_buf_list[i]) {
596 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800597 mwifiex_unmap_pci_memory(adapter, skb,
598 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800599 dev_kfree_skb_any(skb);
600 }
601 memset(desc2, 0, sizeof(*desc2));
602 } else {
603 desc = card->rxbd_ring[i];
604 if (card->rx_buf_list[i]) {
605 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800606 mwifiex_unmap_pci_memory(adapter, skb,
607 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800608 dev_kfree_skb_any(skb);
609 }
610 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800611 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800612 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800613 }
614
615 return;
616}
617
618/* This function cleans up event buffer rings. If any of the buffer list has
619 * valid SKB address, associated SKB is freed.
620 */
621static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
622{
623 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800624 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800625 struct sk_buff *skb;
626 int i;
627
628 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
629 desc = card->evtbd_ring[i];
630 if (card->evt_buf_list[i]) {
631 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800632 mwifiex_unmap_pci_memory(adapter, skb,
633 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800634 dev_kfree_skb_any(skb);
635 }
636 card->evt_buf_list[i] = NULL;
637 memset(desc, 0, sizeof(*desc));
638 }
639
640 return;
641}
642
643/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700644 */
645static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
646{
647 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800648 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700649
650 /*
651 * driver maintaines the write pointer and firmware maintaines the read
652 * pointer. The write pointer starts at 0 (zero) while the read pointer
653 * starts at zero with rollover bit set
654 */
655 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800656
657 if (reg->pfu_enabled)
658 card->txbd_rdptr = 0;
659 else
660 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700661
662 /* allocate shared memory for the BD ring and divide the same in to
663 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800664 if (reg->pfu_enabled)
665 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
666 MWIFIEX_MAX_TXRX_BD;
667 else
668 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
669 MWIFIEX_MAX_TXRX_BD;
670
Amitkumar Karward930fae2011-10-11 17:41:21 -0700671 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700672 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800673 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
674 card->txbd_ring_size,
675 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700676 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800677 dev_err(adapter->dev,
678 "allocate consistent memory (%d bytes) failed!\n",
679 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800680 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700681 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700682 dev_dbg(adapter->dev,
683 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800684 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700685 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700686
Avinash Patil07324842013-02-08 18:18:07 -0800687 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700688}
689
690static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
691{
692 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800693 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700694
Avinash Patil07324842013-02-08 18:18:07 -0800695 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700696
Avinash Patilfc331462013-01-03 21:21:30 -0800697 if (card->txbd_ring_vbase)
698 pci_free_consistent(card->dev, card->txbd_ring_size,
699 card->txbd_ring_vbase,
700 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700701 card->txbd_ring_size = 0;
702 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800703 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700704 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800705 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700706
707 return 0;
708}
709
710/*
711 * This function creates buffer descriptor ring for RX
712 */
713static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
714{
715 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800716 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700717
718 /*
719 * driver maintaines the read pointer and firmware maintaines the write
720 * pointer. The write pointer starts at 0 (zero) while the read pointer
721 * starts at zero with rollover bit set
722 */
723 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800724 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700725
Avinash Patilca8f2112013-02-08 18:18:09 -0800726 if (reg->pfu_enabled)
727 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
728 MWIFIEX_MAX_TXRX_BD;
729 else
730 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
731 MWIFIEX_MAX_TXRX_BD;
732
Amitkumar Karward930fae2011-10-11 17:41:21 -0700733 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700734 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800735 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
736 card->rxbd_ring_size,
737 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700738 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800739 dev_err(adapter->dev,
740 "allocate consistent memory (%d bytes) failed!\n",
741 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800742 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700743 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700744
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700745 dev_dbg(adapter->dev,
746 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
747 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
748 (u32)((u64)card->rxbd_ring_pbase >> 32),
749 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700750
Avinash Patil07324842013-02-08 18:18:07 -0800751 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700752}
753
754/*
755 * This function deletes Buffer descriptor ring for RX
756 */
757static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
758{
759 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800760 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700761
Avinash Patil07324842013-02-08 18:18:07 -0800762 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700763
Avinash Patilfc331462013-01-03 21:21:30 -0800764 if (card->rxbd_ring_vbase)
765 pci_free_consistent(card->dev, card->rxbd_ring_size,
766 card->rxbd_ring_vbase,
767 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700768 card->rxbd_ring_size = 0;
769 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800770 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700771 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800772 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700773
774 return 0;
775}
776
777/*
778 * This function creates buffer descriptor ring for Events
779 */
780static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
781{
782 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800783 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700784
785 /*
786 * driver maintaines the read pointer and firmware maintaines the write
787 * pointer. The write pointer starts at 0 (zero) while the read pointer
788 * starts at zero with rollover bit set
789 */
790 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800791 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700792
Avinash Patile05dc3e2013-02-08 18:18:08 -0800793 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800794 MWIFIEX_MAX_EVT_BD;
795
Amitkumar Karward930fae2011-10-11 17:41:21 -0700796 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700797 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800798 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
799 card->evtbd_ring_size,
800 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700801 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700802 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800803 "allocate consistent memory (%d bytes) failed!\n",
804 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800805 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700806 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700807
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700808 dev_dbg(adapter->dev,
809 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
810 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
811 (u32)((u64)card->evtbd_ring_pbase >> 32),
812 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700813
Avinash Patil07324842013-02-08 18:18:07 -0800814 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700815}
816
817/*
818 * This function deletes Buffer descriptor ring for Events
819 */
820static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
821{
822 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800823 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700824
Avinash Patil07324842013-02-08 18:18:07 -0800825 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700826
Avinash Patilfc331462013-01-03 21:21:30 -0800827 if (card->evtbd_ring_vbase)
828 pci_free_consistent(card->dev, card->evtbd_ring_size,
829 card->evtbd_ring_vbase,
830 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700831 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800832 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700833 card->evtbd_ring_size = 0;
834 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800835 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700836
837 return 0;
838}
839
840/*
841 * This function allocates a buffer for CMDRSP
842 */
843static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
844{
845 struct pcie_service_card *card = adapter->card;
846 struct sk_buff *skb;
847
848 /* Allocate memory for receiving command response data */
849 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
850 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700851 dev_err(adapter->dev,
852 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700853 return -ENOMEM;
854 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700855 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800856 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
857 PCI_DMA_FROMDEVICE))
858 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700859
Avinash Patilfc331462013-01-03 21:21:30 -0800860 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700861
862 return 0;
863}
864
865/*
866 * This function deletes a buffer for CMDRSP
867 */
868static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
869{
870 struct pcie_service_card *card;
871
872 if (!adapter)
873 return 0;
874
875 card = adapter->card;
876
Avinash Patilfc331462013-01-03 21:21:30 -0800877 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800878 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
879 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700880 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800881 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700882
Avinash Patilfc331462013-01-03 21:21:30 -0800883 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800884 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
885 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800886 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700887 return 0;
888}
889
890/*
891 * This function allocates a buffer for sleep cookie
892 */
893static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
894{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700895 struct pcie_service_card *card = adapter->card;
896
Avinash Patilfc331462013-01-03 21:21:30 -0800897 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
898 &card->sleep_cookie_pbase);
899 if (!card->sleep_cookie_vbase) {
900 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700901 return -ENOMEM;
902 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700903 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800904 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700905
906 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800907 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700908
909 return 0;
910}
911
912/*
913 * This function deletes buffer for sleep cookie
914 */
915static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
916{
917 struct pcie_service_card *card;
918
919 if (!adapter)
920 return 0;
921
922 card = adapter->card;
923
Avinash Patilfc331462013-01-03 21:21:30 -0800924 if (card && card->sleep_cookie_vbase) {
925 pci_free_consistent(card->dev, sizeof(u32),
926 card->sleep_cookie_vbase,
927 card->sleep_cookie_pbase);
928 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700929 }
930
931 return 0;
932}
933
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800934/* This function flushes the TX buffer descriptor ring
935 * This function defined as handler is also called while cleaning TXRX
936 * during disconnect/ bss stop.
937 */
938static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
939{
940 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800941
Avinash Patil48f4d912013-02-20 21:12:58 -0800942 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800943 card->txbd_flush = 1;
944 /* write pointer already set at last send
945 * send dnld-rdy intr again, wait for completion.
946 */
947 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
948 CPU_INTR_DNLD_RDY)) {
949 dev_err(adapter->dev,
950 "failed to assert dnld-rdy interrupt.\n");
951 return -1;
952 }
953 }
954 return 0;
955}
956
Amitkumar Karward930fae2011-10-11 17:41:21 -0700957/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800958 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700959 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800960static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700961{
Avinash Patile7f767a2013-01-03 21:21:32 -0800962 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800963 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800964 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800965 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700966 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800967 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700968
969 if (!mwifiex_pcie_ok_to_access_hw(adapter))
970 mwifiex_pm_wakeup_card(adapter);
971
972 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800973 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700974 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800975 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700976 return -1;
977 }
978
Avinash Patile7f767a2013-01-03 21:21:32 -0800979 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
980 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700981
Avinash Patilca8f2112013-02-08 18:18:09 -0800982 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800983 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800984 while (((card->txbd_rdptr & reg->tx_mask) !=
985 (rdptr & reg->tx_mask)) ||
986 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
987 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800988 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
989 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800990
991 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -0800992
Avinash Patile7f767a2013-01-03 21:21:32 -0800993 if (skb) {
994 dev_dbg(adapter->dev,
995 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
996 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -0800997 mwifiex_unmap_pci_memory(adapter, skb,
998 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -0800999
1000 unmap_count++;
1001
1002 if (card->txbd_flush)
1003 mwifiex_write_data_complete(adapter, skb, 0,
1004 -1);
1005 else
1006 mwifiex_write_data_complete(adapter, skb, 0, 0);
1007 }
1008
1009 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001010
1011 if (reg->pfu_enabled) {
1012 desc2 = (void *)card->txbd_ring[wrdoneidx];
1013 memset(desc2, 0, sizeof(*desc2));
1014 } else {
1015 desc = card->txbd_ring[wrdoneidx];
1016 memset(desc, 0, sizeof(*desc));
1017 }
1018 switch (card->dev->device) {
1019 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1020 card->txbd_rdptr++;
1021 break;
1022 case PCIE_DEVICE_ID_MARVELL_88W8897:
1023 card->txbd_rdptr += reg->ring_tx_start_ptr;
1024 break;
1025 }
1026
Avinash Patile7f767a2013-01-03 21:21:32 -08001027
Avinash Patildd04e6a2013-02-08 18:18:06 -08001028 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001029 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001030 reg->tx_rollover_ind) ^
1031 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001032 }
1033
1034 if (unmap_count)
1035 adapter->data_sent = false;
1036
1037 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001038 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001039 card->txbd_flush = 0;
1040 else
1041 mwifiex_clean_pcie_ring_buf(adapter);
1042 }
1043
1044 return 0;
1045}
1046
1047/* This function sends data buffer to device. First 4 bytes of payload
1048 * are filled with payload length and payload type. Then this payload
1049 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1050 * Download ready interrupt to FW is deffered if Tx ring is not full and
1051 * additional payload can be accomodated.
1052 */
1053static int
1054mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1055 struct mwifiex_tx_param *tx_param)
1056{
1057 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001058 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001059 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001060 int ret;
1061 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001062 struct mwifiex_pcie_buf_desc *desc = NULL;
1063 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001064 __le16 *tmp;
1065
1066 if (!(skb->data && skb->len)) {
1067 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1068 __func__, skb->data, skb->len);
1069 return -1;
1070 }
1071
1072 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1073 mwifiex_pm_wakeup_card(adapter);
1074
Avinash Patilca8f2112013-02-08 18:18:09 -08001075 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001076 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1077 card->txbd_rdptr, card->txbd_wrptr);
1078 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001079 u8 *payload;
1080
1081 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001082 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001083 tmp = (__le16 *)&payload[0];
1084 *tmp = cpu_to_le16((u16)skb->len);
1085 tmp = (__le16 *)&payload[2];
1086 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001087
Aaron Durbindbccc922014-02-07 16:25:50 -08001088 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001089 PCI_DMA_TODEVICE))
1090 return -1;
1091
Avinash Patilca8f2112013-02-08 18:18:09 -08001092 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001093 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001094 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001095
Avinash Patilca8f2112013-02-08 18:18:09 -08001096 if (reg->pfu_enabled) {
1097 desc2 = (void *)card->txbd_ring[wrindx];
1098 desc2->paddr = buf_pa;
1099 desc2->len = (u16)skb->len;
1100 desc2->frag_len = (u16)skb->len;
1101 desc2->offset = 0;
1102 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1103 MWIFIEX_BD_FLAG_LAST_DESC;
1104 } else {
1105 desc = card->txbd_ring[wrindx];
1106 desc->paddr = buf_pa;
1107 desc->len = (u16)skb->len;
1108 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1109 MWIFIEX_BD_FLAG_LAST_DESC;
1110 }
1111
1112 switch (card->dev->device) {
1113 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1114 card->txbd_wrptr++;
1115 break;
1116 case PCIE_DEVICE_ID_MARVELL_88W8897:
1117 card->txbd_wrptr += reg->ring_tx_start_ptr;
1118 break;
1119 }
1120
1121 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001122 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001123 reg->tx_rollover_ind) ^
1124 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001125
Avinash Patilca8f2112013-02-08 18:18:09 -08001126 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001127 /* Write the TX ring write pointer in to reg->tx_wrptr */
1128 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001129 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001130 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001131 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001132 ret = -1;
1133 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001134 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001135 if ((mwifiex_pcie_txbd_not_full(card)) &&
1136 tx_param->next_pkt_len) {
1137 /* have more packets and TxBD still can hold more */
1138 dev_dbg(adapter->dev,
1139 "SEND DATA: delay dnld-rdy interrupt.\n");
1140 adapter->data_sent = false;
1141 } else {
1142 /* Send the TX ready interrupt */
1143 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1144 CPU_INTR_DNLD_RDY)) {
1145 dev_err(adapter->dev,
1146 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1147 ret = -1;
1148 goto done_unmap;
1149 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001150 }
1151 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001152 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001153 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001154 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001155 dev_dbg(adapter->dev,
1156 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001157 adapter->data_sent = true;
1158 /* Send the TX ready interrupt */
1159 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1160 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001161 dev_err(adapter->dev,
1162 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001163 return -EBUSY;
1164 }
1165
Avinash Patile7f767a2013-01-03 21:21:32 -08001166 return -EINPROGRESS;
1167done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001168 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001169 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001170 if (reg->pfu_enabled)
1171 memset(desc2, 0, sizeof(*desc2));
1172 else
1173 memset(desc, 0, sizeof(*desc));
1174
Avinash Patile7f767a2013-01-03 21:21:32 -08001175 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001176}
1177
1178/*
1179 * This function handles received buffer ring and
1180 * dispatches packets to upper
1181 */
1182static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1183{
1184 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001185 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001186 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001187 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001188 int ret = 0;
1189 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001190 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001191 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001192
Avinash Patile7f767a2013-01-03 21:21:32 -08001193 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1194 mwifiex_pm_wakeup_card(adapter);
1195
Amitkumar Karward930fae2011-10-11 17:41:21 -07001196 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001197 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001198 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001199 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001200 ret = -1;
1201 goto done;
1202 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001203 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001204
Avinash Patildd04e6a2013-02-08 18:18:06 -08001205 while (((wrptr & reg->rx_mask) !=
1206 (card->rxbd_rdptr & reg->rx_mask)) ||
1207 ((wrptr & reg->rx_rollover_ind) ==
1208 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001209 struct sk_buff *skb_data;
1210 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001211 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001212
Avinash Patildd04e6a2013-02-08 18:18:06 -08001213 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001214 skb_data = card->rx_buf_list[rd_index];
1215
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001216 /* If skb allocation was failed earlier for Rx packet,
1217 * rx_buf_list[rd_index] would have been left with a NULL.
1218 */
1219 if (!skb_data)
1220 return -ENOMEM;
1221
Aaron Durbindbccc922014-02-07 16:25:50 -08001222 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001223 card->rx_buf_list[rd_index] = NULL;
1224
Amitkumar Karward930fae2011-10-11 17:41:21 -07001225 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001226 * first 2 bytes for len, next 2 bytes is for type
1227 */
1228 pkt_len = *((__le16 *)skb_data->data);
1229 rx_len = le16_to_cpu(pkt_len);
1230 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001231 dev_dbg(adapter->dev,
1232 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1233 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001234 skb_pull(skb_data, INTF_HEADER_LEN);
1235 mwifiex_handle_rx_packet(adapter, skb_data);
1236
1237 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001238 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001239 dev_err(adapter->dev,
1240 "Unable to allocate skb.\n");
1241 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001242 }
1243
Avinash Patile7f767a2013-01-03 21:21:32 -08001244 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1245 MWIFIEX_RX_DATA_BUF_SIZE,
1246 PCI_DMA_FROMDEVICE))
1247 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001248
Aaron Durbindbccc922014-02-07 16:25:50 -08001249 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001250
1251 dev_dbg(adapter->dev,
1252 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1253 skb_tmp, rd_index);
1254 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001255
1256 if (reg->pfu_enabled) {
1257 desc2 = (void *)card->rxbd_ring[rd_index];
1258 desc2->paddr = buf_pa;
1259 desc2->len = skb_tmp->len;
1260 desc2->frag_len = skb_tmp->len;
1261 desc2->offset = 0;
1262 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1263 } else {
1264 desc = card->rxbd_ring[rd_index];
1265 desc->paddr = buf_pa;
1266 desc->len = skb_tmp->len;
1267 desc->flags = 0;
1268 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001269
Avinash Patildd04e6a2013-02-08 18:18:06 -08001270 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001271 MWIFIEX_MAX_TXRX_BD) {
1272 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001273 reg->rx_rollover_ind) ^
1274 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001275 }
1276 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001277 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001278
Avinash Patilca8f2112013-02-08 18:18:09 -08001279 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001280 /* Write the RX ring read pointer in to reg->rx_rdptr */
1281 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001282 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001283 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001284 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001285 ret = -1;
1286 goto done;
1287 }
1288
1289 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001290 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001291 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001292 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001293 ret = -1;
1294 goto done;
1295 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001296 dev_dbg(adapter->dev,
1297 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001298 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001299 }
1300
1301done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001302 return ret;
1303}
1304
1305/*
1306 * This function downloads the boot command to device
1307 */
1308static int
1309mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1310{
Avinash Patilfc331462013-01-03 21:21:30 -08001311 dma_addr_t buf_pa;
1312 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001313 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001314
Avinash Patilfc331462013-01-03 21:21:30 -08001315 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001316 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001317 "Invalid parameter in %s <%p. len %d>\n",
1318 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001319 return -1;
1320 }
1321
Avinash Patilfc331462013-01-03 21:21:30 -08001322 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1323 return -1;
1324
Aaron Durbindbccc922014-02-07 16:25:50 -08001325 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001326
Avinash Patildd04e6a2013-02-08 18:18:06 -08001327 /* Write the lower 32bits of the physical address to low command
1328 * address scratch register
1329 */
1330 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001331 dev_err(adapter->dev,
1332 "%s: failed to write download command to boot code.\n",
1333 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001334 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001335 return -1;
1336 }
1337
Avinash Patildd04e6a2013-02-08 18:18:06 -08001338 /* Write the upper 32bits of the physical address to high command
1339 * address scratch register
1340 */
1341 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001342 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001343 dev_err(adapter->dev,
1344 "%s: failed to write download command to boot code.\n",
1345 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001346 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001347 return -1;
1348 }
1349
Avinash Patildd04e6a2013-02-08 18:18:06 -08001350 /* Write the command length to cmd_size scratch register */
1351 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001352 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001353 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001354 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001355 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001356 return -1;
1357 }
1358
1359 /* Ring the door bell */
1360 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1361 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001362 dev_err(adapter->dev,
1363 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001364 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001365 return -1;
1366 }
1367
1368 return 0;
1369}
1370
Avinash Patilc6d1d872013-01-03 21:21:29 -08001371/* This function init rx port in firmware which in turn enables to receive data
1372 * from device before transmitting any packet.
1373 */
1374static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1375{
1376 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001377 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001378 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001379
Avinash Patildd04e6a2013-02-08 18:18:06 -08001380 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001381 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1382 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001383 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001384 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001385 return -1;
1386 }
1387 return 0;
1388}
1389
1390/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001391 */
1392static int
1393mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1394{
1395 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001396 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001397 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001398 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1399 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001400
1401 if (!(skb->data && skb->len)) {
1402 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001403 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001404 return -1;
1405 }
1406
1407 /* Make sure a command response buffer is available */
1408 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001409 dev_err(adapter->dev,
1410 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001411 return -EBUSY;
1412 }
1413
Avinash Patilfc331462013-01-03 21:21:30 -08001414 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1415 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001416
1417 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001418
1419 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1420 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1421
1422 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1423 return -1;
1424
1425 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001426
1427 /* To send a command, the driver will:
1428 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001429 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001430 2. Ring the door bell (i.e. set the door bell interrupt)
1431
1432 In response to door bell interrupt, the firmware will perform
1433 the DMA of the command packet (first header to obtain the total
1434 length and then rest of the command).
1435 */
1436
1437 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001438 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001439 /* Write the lower 32bits of the cmdrsp buffer physical
1440 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001441 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001442 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001443 dev_err(adapter->dev,
1444 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001445 ret = -1;
1446 goto done;
1447 }
1448 /* Write the upper 32bits of the cmdrsp buffer physical
1449 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001450 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001451 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001452 dev_err(adapter->dev,
1453 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001454 ret = -1;
1455 goto done;
1456 }
1457 }
1458
Aaron Durbindbccc922014-02-07 16:25:50 -08001459 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001460 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1461 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1462 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001463 dev_err(adapter->dev,
1464 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001465 ret = -1;
1466 goto done;
1467 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001468 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1469 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001470 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001471 dev_err(adapter->dev,
1472 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001473 ret = -1;
1474 goto done;
1475 }
1476
Avinash Patildd04e6a2013-02-08 18:18:06 -08001477 /* Write the command length to reg->cmd_size */
1478 if (mwifiex_write_reg(adapter, reg->cmd_size,
1479 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001480 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001481 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001482 ret = -1;
1483 goto done;
1484 }
1485
1486 /* Ring the door bell */
1487 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1488 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001489 dev_err(adapter->dev,
1490 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001491 ret = -1;
1492 goto done;
1493 }
1494
1495done:
1496 if (ret)
1497 adapter->cmd_sent = false;
1498
1499 return 0;
1500}
1501
1502/*
1503 * This function handles command complete interrupt
1504 */
1505static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1506{
1507 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001508 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001509 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001510 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001511 u16 rx_len;
1512 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001513
1514 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1515
Aaron Durbindbccc922014-02-07 16:25:50 -08001516 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001517
Aaron Durbin189b3292014-02-07 16:25:51 -08001518 /* Unmap the command as a response has been received. */
1519 if (card->cmd_buf) {
1520 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1521 PCI_DMA_TODEVICE);
1522 card->cmd_buf = NULL;
1523 }
1524
Avinash Patilfc331462013-01-03 21:21:30 -08001525 pkt_len = *((__le16 *)skb->data);
1526 rx_len = le16_to_cpu(pkt_len);
1527 skb_trim(skb, rx_len);
1528 skb_pull(skb, INTF_HEADER_LEN);
1529
Amitkumar Karward930fae2011-10-11 17:41:21 -07001530 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001531 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001532 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1533 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001534 mwifiex_pcie_enable_host_int(adapter);
1535 if (mwifiex_write_reg(adapter,
1536 PCIE_CPU_INT_EVENT,
1537 CPU_INTR_SLEEP_CFM_DONE)) {
1538 dev_warn(adapter->dev,
1539 "Write register failed\n");
1540 return -1;
1541 }
Avinash Patil52301a82013-02-12 14:38:32 -08001542 while (reg->sleep_cookie && (count++ < 10) &&
1543 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001544 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001545 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001546 dev_err(adapter->dev,
1547 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001548 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001549 memcpy(adapter->upld_buf, skb->data,
1550 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001551 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001552 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1553 PCI_DMA_FROMDEVICE))
1554 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001555 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001556 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001557 adapter->cmd_resp_received = true;
1558 /* Take the pointer and set it to CMD node and will
1559 return in the response complete callback */
1560 card->cmdrsp_buf = NULL;
1561
1562 /* Clear the cmd-rsp buffer address in scratch registers. This
1563 will prevent firmware from writing to the same response
1564 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001565 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001566 dev_err(adapter->dev,
1567 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001568 return -1;
1569 }
1570 /* Write the upper 32bits of the cmdrsp buffer physical
1571 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001572 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001573 dev_err(adapter->dev,
1574 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001575 return -1;
1576 }
1577 }
1578
1579 return 0;
1580}
1581
1582/*
1583 * Command Response processing complete handler
1584 */
1585static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1586 struct sk_buff *skb)
1587{
1588 struct pcie_service_card *card = adapter->card;
1589
1590 if (skb) {
1591 card->cmdrsp_buf = skb;
1592 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001593 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1594 PCI_DMA_FROMDEVICE))
1595 return -1;
1596 }
1597
Amitkumar Karward930fae2011-10-11 17:41:21 -07001598 return 0;
1599}
1600
1601/*
1602 * This function handles firmware event ready interrupt
1603 */
1604static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1605{
1606 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001607 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001608 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1609 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001610 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001611
1612 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1613 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001614
1615 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001616 dev_dbg(adapter->dev, "info: Event being processed, "
1617 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001618 return 0;
1619 }
1620
1621 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1622 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1623 return -1;
1624 }
1625
1626 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001627 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001628 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001629 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001630 return -1;
1631 }
1632
1633 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001634 card->evtbd_rdptr, wrptr);
1635 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1636 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001637 ((wrptr & reg->evt_rollover_ind) ==
1638 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001639 struct sk_buff *skb_cmd;
1640 __le16 data_len = 0;
1641 u16 evt_len;
1642
1643 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1644 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001645 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001646
Amitkumar Karward930fae2011-10-11 17:41:21 -07001647 /* Take the pointer and set it to event pointer in adapter
1648 and will return back after event handling callback */
1649 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001650 desc = card->evtbd_ring[rdptr];
1651 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001652
1653 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1654 adapter->event_cause = event;
1655 /* The first 4bytes will be the event transfer header
1656 len is 2 bytes followed by type which is 2 bytes */
1657 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1658 evt_len = le16_to_cpu(data_len);
1659
1660 skb_pull(skb_cmd, INTF_HEADER_LEN);
1661 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1662
1663 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1664 memcpy(adapter->event_body, skb_cmd->data +
1665 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1666 MWIFIEX_EVENT_HEADER_LEN);
1667
1668 adapter->event_received = true;
1669 adapter->event_skb = skb_cmd;
1670
1671 /* Do not update the event read pointer here, wait till the
1672 buffer is released. This is just to make things simpler,
1673 we need to find a better method of managing these buffers.
1674 */
1675 }
1676
1677 return 0;
1678}
1679
1680/*
1681 * Event processing complete handler
1682 */
1683static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1684 struct sk_buff *skb)
1685{
1686 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001687 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001688 int ret = 0;
1689 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1690 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001691 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001692
1693 if (!skb)
1694 return 0;
1695
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001696 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001697 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001698 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001699 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001700 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001701
1702 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001703 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001704 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001705 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001706 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001707 }
1708
1709 if (!card->evt_buf_list[rdptr]) {
1710 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001711 if (mwifiex_map_pci_memory(adapter, skb,
1712 MAX_EVENT_SIZE,
1713 PCI_DMA_FROMDEVICE))
1714 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001715 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001716 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001717 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001718 desc->len = (u16)skb->len;
1719 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001720 skb = NULL;
1721 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001722 dev_dbg(adapter->dev,
1723 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1724 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001725 }
1726
1727 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1728 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001729 reg->evt_rollover_ind) ^
1730 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001731 }
1732
1733 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001734 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001735
Avinash Patildd04e6a2013-02-08 18:18:06 -08001736 /* Write the event ring read pointer in to reg->evt_rdptr */
1737 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1738 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001739 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001740 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001741 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001742 }
1743
Amitkumar Karward930fae2011-10-11 17:41:21 -07001744 dev_dbg(adapter->dev, "info: Check Events Again\n");
1745 ret = mwifiex_pcie_process_event_ready(adapter);
1746
1747 return ret;
1748}
1749
1750/*
1751 * This function downloads the firmware to the card.
1752 *
1753 * Firmware is downloaded to the card in blocks. Every block download
1754 * is tested for CRC errors, and retried a number of times before
1755 * returning failure.
1756 */
1757static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1758 struct mwifiex_fw_image *fw)
1759{
1760 int ret;
1761 u8 *firmware = fw->fw_buf;
1762 u32 firmware_len = fw->fw_len;
1763 u32 offset = 0;
1764 struct sk_buff *skb;
1765 u32 txlen, tx_blocks = 0, tries, len;
1766 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001767 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001768 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001769
1770 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001771 dev_err(adapter->dev,
1772 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001773 return -1;
1774 }
1775
1776 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001777 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001778
1779 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001780 dev_err(adapter->dev,
1781 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001782 return -1;
1783 }
1784
1785 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1786 if (!skb) {
1787 ret = -ENOMEM;
1788 goto done;
1789 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001790
1791 /* Perform firmware data transfer */
1792 do {
1793 u32 ireg_intr = 0;
1794
1795 /* More data? */
1796 if (offset >= firmware_len)
1797 break;
1798
1799 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001800 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001801 &len);
1802 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001803 dev_warn(adapter->dev,
1804 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001805 goto done;
1806 }
1807 if (len)
1808 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001809 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001810 }
1811
1812 if (!len) {
1813 break;
1814 } else if (len > MWIFIEX_UPLD_SIZE) {
1815 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001816 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001817 ret = -1;
1818 goto done;
1819 }
1820
1821 txlen = len;
1822
1823 if (len & BIT(0)) {
1824 block_retry_cnt++;
1825 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1826 pr_err("FW download failure @ %d, over max "
1827 "retry count\n", offset);
1828 ret = -1;
1829 goto done;
1830 }
1831 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001832 "helper: len = 0x%04X, txlen = %d\n",
1833 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001834 len &= ~BIT(0);
1835 /* Setting this to 0 to resend from same offset */
1836 txlen = 0;
1837 } else {
1838 block_retry_cnt = 0;
1839 /* Set blocksize to transfer - checking for
1840 last block */
1841 if (firmware_len - offset < txlen)
1842 txlen = firmware_len - offset;
1843
1844 dev_dbg(adapter->dev, ".");
1845
Avinash Patildd04e6a2013-02-08 18:18:06 -08001846 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1847 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001848
1849 /* Copy payload to buffer */
1850 memmove(skb->data, &firmware[offset], txlen);
1851 }
1852
1853 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001854 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001855
1856 /* Send the boot command to device */
1857 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001858 dev_err(adapter->dev,
1859 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001860 ret = -1;
1861 goto done;
1862 }
Avinash Patilfc331462013-01-03 21:21:30 -08001863
Amitkumar Karward930fae2011-10-11 17:41:21 -07001864 /* Wait for the command done interrupt */
1865 do {
1866 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1867 &ireg_intr)) {
1868 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001869 "interrupt status during fw dnld.\n",
1870 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001871 mwifiex_unmap_pci_memory(adapter, skb,
1872 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001873 ret = -1;
1874 goto done;
1875 }
1876 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1877 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001878
Aaron Durbindbccc922014-02-07 16:25:50 -08001879 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001880
Amitkumar Karward930fae2011-10-11 17:41:21 -07001881 offset += txlen;
1882 } while (true);
1883
1884 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001885 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001886
1887 ret = 0;
1888
1889done:
1890 dev_kfree_skb_any(skb);
1891 return ret;
1892}
1893
1894/*
1895 * This function checks the firmware status in card.
1896 *
1897 * The winner interface is also determined by this function.
1898 */
1899static int
1900mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1901{
1902 int ret = 0;
1903 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001904 struct pcie_service_card *card = adapter->card;
1905 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001906 u32 tries;
1907
1908 /* Mask spurios interrupts */
1909 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001910 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001911 dev_warn(adapter->dev, "Write register failed\n");
1912 return -1;
1913 }
1914
1915 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001916 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1917 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001918 dev_err(adapter->dev,
1919 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001920 return -1;
1921 }
1922
1923 /* Wait for firmware initialization event */
1924 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001925 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001926 &firmware_stat))
1927 ret = -1;
1928 else
1929 ret = 0;
1930 if (ret)
1931 continue;
1932 if (firmware_stat == FIRMWARE_READY_PCIE) {
1933 ret = 0;
1934 break;
1935 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07001936 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001937 ret = -1;
1938 }
1939 }
1940
1941 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001942 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001943 &winner_status))
1944 ret = -1;
1945 else if (!winner_status) {
1946 dev_err(adapter->dev, "PCI-E is the winner\n");
1947 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001948 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001949 dev_err(adapter->dev,
1950 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1951 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001952 }
1953 }
1954
1955 return ret;
1956}
1957
1958/*
1959 * This function reads the interrupt status from card.
1960 */
1961static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1962{
1963 u32 pcie_ireg;
1964 unsigned long flags;
1965
1966 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1967 return;
1968
1969 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1970 dev_warn(adapter->dev, "Read register failed\n");
1971 return;
1972 }
1973
1974 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1975
1976 mwifiex_pcie_disable_host_int(adapter);
1977
1978 /* Clear the pending interrupts */
1979 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1980 ~pcie_ireg)) {
1981 dev_warn(adapter->dev, "Write register failed\n");
1982 return;
1983 }
1984 spin_lock_irqsave(&adapter->int_lock, flags);
1985 adapter->int_status |= pcie_ireg;
1986 spin_unlock_irqrestore(&adapter->int_lock, flags);
1987
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001988 if (!adapter->pps_uapsd_mode &&
1989 adapter->ps_state == PS_STATE_SLEEP &&
1990 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001991 /* Potentially for PCIe we could get other
1992 * interrupts like shared. Don't change power
1993 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07001994 adapter->ps_state = PS_STATE_AWAKE;
1995 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001996 }
1997 }
1998}
1999
2000/*
2001 * Interrupt handler for PCIe root port
2002 *
2003 * This function reads the interrupt status from firmware and assigns
2004 * the main process in workqueue which will handle the interrupt.
2005 */
2006static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2007{
2008 struct pci_dev *pdev = (struct pci_dev *)context;
2009 struct pcie_service_card *card;
2010 struct mwifiex_adapter *adapter;
2011
2012 if (!pdev) {
2013 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2014 goto exit;
2015 }
2016
Jingoo Hanb2a31202013-09-09 14:26:51 +09002017 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002018 if (!card || !card->adapter) {
2019 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002020 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002021 goto exit;
2022 }
2023 adapter = card->adapter;
2024
2025 if (adapter->surprise_removed)
2026 goto exit;
2027
2028 mwifiex_interrupt_status(adapter);
2029 queue_work(adapter->workqueue, &adapter->main_work);
2030
2031exit:
2032 return IRQ_HANDLED;
2033}
2034
2035/*
2036 * This function checks the current interrupt status.
2037 *
2038 * The following interrupts are checked and handled by this function -
2039 * - Data sent
2040 * - Command sent
2041 * - Command received
2042 * - Packets received
2043 * - Events received
2044 *
2045 * In case of Rx packets received, the packets are uploaded from card to
2046 * host and processed accordingly.
2047 */
2048static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2049{
2050 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002051 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002052 unsigned long flags;
2053
2054 spin_lock_irqsave(&adapter->int_lock, flags);
2055 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002056 pcie_ireg = adapter->int_status;
2057 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002058 spin_unlock_irqrestore(&adapter->int_lock, flags);
2059
Avinash Patil659c4782013-01-03 21:21:28 -08002060 while (pcie_ireg & HOST_INTR_MASK) {
2061 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2062 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002063 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2064 ret = mwifiex_pcie_send_data_complete(adapter);
2065 if (ret)
2066 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002067 }
Avinash Patil659c4782013-01-03 21:21:28 -08002068 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2069 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002070 dev_dbg(adapter->dev, "info: Rx DATA\n");
2071 ret = mwifiex_pcie_process_recv_data(adapter);
2072 if (ret)
2073 return ret;
2074 }
Avinash Patil659c4782013-01-03 21:21:28 -08002075 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2076 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002077 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2078 ret = mwifiex_pcie_process_event_ready(adapter);
2079 if (ret)
2080 return ret;
2081 }
2082
Avinash Patil659c4782013-01-03 21:21:28 -08002083 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2084 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002085 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002086 dev_dbg(adapter->dev,
2087 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002088 adapter->cmd_sent = false;
2089 }
2090 /* Handle command response */
2091 ret = mwifiex_pcie_process_cmd_complete(adapter);
2092 if (ret)
2093 return ret;
2094 }
2095
2096 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2097 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2098 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002099 dev_warn(adapter->dev,
2100 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002101 return -1;
2102 }
2103
2104 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2105 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002106 PCIE_HOST_INT_STATUS,
2107 ~pcie_ireg)) {
2108 dev_warn(adapter->dev,
2109 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002110 return -1;
2111 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002112 }
2113
2114 }
2115 }
2116 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002117 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002118 if (adapter->ps_state != PS_STATE_SLEEP)
2119 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002120
2121 return 0;
2122}
2123
2124/*
2125 * This function downloads data from driver to card.
2126 *
2127 * Both commands and data packets are transferred to the card by this
2128 * function.
2129 *
2130 * This function adds the PCIE specific header to the front of the buffer
2131 * before transferring. The header contains the length of the packet and
2132 * the type. The firmware handles the packets based upon this set type.
2133 */
2134static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2135 struct sk_buff *skb,
2136 struct mwifiex_tx_param *tx_param)
2137{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002138 if (!skb) {
2139 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002140 return -1;
2141 }
2142
2143 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002144 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002145 else if (type == MWIFIEX_TYPE_CMD)
2146 return mwifiex_pcie_send_cmd(adapter, skb);
2147
2148 return 0;
2149}
2150
2151/*
2152 * This function initializes the PCI-E host memory space, WCB rings, etc.
2153 *
2154 * The following initializations steps are followed -
2155 * - Allocate TXBD ring buffers
2156 * - Allocate RXBD ring buffers
2157 * - Allocate event BD ring buffers
2158 * - Allocate command response ring buffer
2159 * - Allocate sleep cookie buffer
2160 */
2161static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2162{
2163 struct pcie_service_card *card = adapter->card;
2164 int ret;
2165 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002166 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002167
2168 pci_set_drvdata(pdev, card);
2169
2170 ret = pci_enable_device(pdev);
2171 if (ret)
2172 goto err_enable_dev;
2173
2174 pci_set_master(pdev);
2175
2176 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2177 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2178 if (ret) {
2179 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2180 goto err_set_dma_mask;
2181 }
2182
2183 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2184 if (ret) {
2185 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2186 goto err_set_dma_mask;
2187 }
2188
2189 ret = pci_request_region(pdev, 0, DRV_NAME);
2190 if (ret) {
2191 dev_err(adapter->dev, "req_reg(0) error\n");
2192 goto err_req_region0;
2193 }
2194 card->pci_mmap = pci_iomap(pdev, 0, 0);
2195 if (!card->pci_mmap) {
2196 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002197 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002198 goto err_iomap0;
2199 }
2200 ret = pci_request_region(pdev, 2, DRV_NAME);
2201 if (ret) {
2202 dev_err(adapter->dev, "req_reg(2) error\n");
2203 goto err_req_region2;
2204 }
2205 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2206 if (!card->pci_mmap1) {
2207 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002208 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002209 goto err_iomap2;
2210 }
2211
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002212 dev_dbg(adapter->dev,
2213 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2214 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002215
2216 card->cmdrsp_buf = NULL;
2217 ret = mwifiex_pcie_create_txbd_ring(adapter);
2218 if (ret)
2219 goto err_cre_txbd;
2220 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2221 if (ret)
2222 goto err_cre_rxbd;
2223 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2224 if (ret)
2225 goto err_cre_evtbd;
2226 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2227 if (ret)
2228 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002229 if (reg->sleep_cookie) {
2230 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2231 if (ret)
2232 goto err_alloc_cookie;
2233 } else {
2234 card->sleep_cookie_vbase = NULL;
2235 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002236 return ret;
2237
2238err_alloc_cookie:
2239 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2240err_alloc_cmdbuf:
2241 mwifiex_pcie_delete_evtbd_ring(adapter);
2242err_cre_evtbd:
2243 mwifiex_pcie_delete_rxbd_ring(adapter);
2244err_cre_rxbd:
2245 mwifiex_pcie_delete_txbd_ring(adapter);
2246err_cre_txbd:
2247 pci_iounmap(pdev, card->pci_mmap1);
2248err_iomap2:
2249 pci_release_region(pdev, 2);
2250err_req_region2:
2251 pci_iounmap(pdev, card->pci_mmap);
2252err_iomap0:
2253 pci_release_region(pdev, 0);
2254err_req_region0:
2255err_set_dma_mask:
2256 pci_disable_device(pdev);
2257err_enable_dev:
2258 pci_set_drvdata(pdev, NULL);
2259 return ret;
2260}
2261
2262/*
2263 * This function cleans up the allocated card buffers.
2264 *
2265 * The following are freed by this function -
2266 * - TXBD ring buffers
2267 * - RXBD ring buffers
2268 * - Event BD ring buffers
2269 * - Command response ring buffer
2270 * - Sleep cookie buffer
2271 */
2272static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2273{
2274 struct pcie_service_card *card = adapter->card;
2275 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002276 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002277
Amitkumar Karward930fae2011-10-11 17:41:21 -07002278 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002279 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002280 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002281 dev_err(adapter->dev,
2282 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002283 }
2284
2285 if (pdev) {
2286 pci_iounmap(pdev, card->pci_mmap);
2287 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002288 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002289 pci_release_region(pdev, 2);
2290 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002291 pci_set_drvdata(pdev, NULL);
2292 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002293 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002294}
2295
2296/*
2297 * This function registers the PCIE device.
2298 *
2299 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2300 */
2301static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2302{
2303 int ret;
2304 struct pcie_service_card *card = adapter->card;
2305 struct pci_dev *pdev = card->dev;
2306
2307 /* save adapter pointer in card */
2308 card->adapter = adapter;
2309
2310 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2311 "MRVL_PCIE", pdev);
2312 if (ret) {
2313 pr_err("request_irq failed: ret=%d\n", ret);
2314 adapter->card = NULL;
2315 return -1;
2316 }
2317
2318 adapter->dev = &pdev->dev;
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002319 adapter->tx_buf_size = card->pcie.tx_buf_size;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002320 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002321
2322 return 0;
2323}
2324
2325/*
2326 * This function unregisters the PCIE device.
2327 *
2328 * The PCIE IRQ is released, the function is disabled and driver
2329 * data is set to null.
2330 */
2331static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2332{
2333 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002334 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002335
2336 if (card) {
2337 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2338 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002339
Avinash Patil52301a82013-02-12 14:38:32 -08002340 reg = card->pcie.reg;
2341 if (reg->sleep_cookie)
2342 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2343
Avinash Patilfc331462013-01-03 21:21:30 -08002344 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2345 mwifiex_pcie_delete_evtbd_ring(adapter);
2346 mwifiex_pcie_delete_rxbd_ring(adapter);
2347 mwifiex_pcie_delete_txbd_ring(adapter);
2348 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002349 }
2350}
2351
2352static struct mwifiex_if_ops pcie_ops = {
2353 .init_if = mwifiex_pcie_init,
2354 .cleanup_if = mwifiex_pcie_cleanup,
2355 .check_fw_status = mwifiex_check_fw_status,
2356 .prog_fw = mwifiex_prog_fw_w_helper,
2357 .register_dev = mwifiex_register_dev,
2358 .unregister_dev = mwifiex_unregister_dev,
2359 .enable_int = mwifiex_pcie_enable_host_int,
2360 .process_int_status = mwifiex_process_int_status,
2361 .host_to_card = mwifiex_pcie_host_to_card,
2362 .wakeup = mwifiex_pm_wakeup_card,
2363 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2364
2365 /* PCIE specific */
2366 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2367 .event_complete = mwifiex_pcie_event_complete,
2368 .update_mp_end_port = NULL,
2369 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002370 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002371 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002372};
2373
2374/*
2375 * This function initializes the PCIE driver module.
2376 *
2377 * This initiates the semaphore and registers the device with
2378 * PCIE bus.
2379 */
2380static int mwifiex_pcie_init_module(void)
2381{
2382 int ret;
2383
Avinash Patilca8f2112013-02-08 18:18:09 -08002384 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002385
2386 sema_init(&add_remove_card_sem, 1);
2387
2388 /* Clear the flag in case user removes the card. */
2389 user_rmmod = 0;
2390
2391 ret = pci_register_driver(&mwifiex_pcie);
2392 if (ret)
2393 pr_err("Driver register failed!\n");
2394 else
2395 pr_debug("info: Driver registered successfully!\n");
2396
2397 return ret;
2398}
2399
2400/*
2401 * This function cleans up the PCIE driver.
2402 *
2403 * The following major steps are followed for cleanup -
2404 * - Resume the device if its suspended
2405 * - Disconnect the device if connected
2406 * - Shutdown the firmware
2407 * - Unregister the device from PCIE bus.
2408 */
2409static void mwifiex_pcie_cleanup_module(void)
2410{
2411 if (!down_interruptible(&add_remove_card_sem))
2412 up(&add_remove_card_sem);
2413
2414 /* Set the flag as user is removing this module. */
2415 user_rmmod = 1;
2416
2417 pci_unregister_driver(&mwifiex_pcie);
2418}
2419
2420module_init(mwifiex_pcie_init_module);
2421module_exit(mwifiex_pcie_cleanup_module);
2422
2423MODULE_AUTHOR("Marvell International Ltd.");
2424MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2425MODULE_VERSION(PCIE_VERSION);
2426MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002427MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2428MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);