blob: a7e8b96b2d9024de8c34e5e04b317c66d2e22820 [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;
Amitkumar Karwarc0dbba62014-03-25 19:01:20 -0700123 adapter->hs_enabling = false;
Bing Zhaofcca8d52013-03-04 16:27:53 -0800124
125 return 0;
126}
127
128/*
129 * Kernel needs to suspend all functions separately. Therefore all
130 * registered functions must have drivers with suspend and resume
131 * methods. Failing that the kernel simply removes the whole card.
132 *
133 * If already not resumed, this function turns on the traffic and
134 * sends a host sleep cancel request to the firmware.
135 */
Shuah Khan3266d732013-07-03 10:47:10 -0600136static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800137{
138 struct mwifiex_adapter *adapter;
139 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600140 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800141
142 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900143 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800144 if (!card || !card->adapter) {
145 pr_err("Card or adapter structure is not valid\n");
146 return 0;
147 }
148 } else {
149 pr_err("PCIE device is not specified\n");
150 return 0;
151 }
152
153 adapter = card->adapter;
154
155 if (!adapter->is_suspended) {
156 dev_warn(adapter->dev, "Device already resumed\n");
157 return 0;
158 }
159
160 adapter->is_suspended = false;
161
162 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
163 MWIFIEX_ASYNC_CMD);
164
165 return 0;
166}
Bing Zhao8509e822013-03-04 16:27:54 -0800167#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800168
169/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700170 * This function probes an mwifiex device and registers it. It allocates
171 * the card structure, enables PCIE function number and initiates the
172 * device registration and initialization procedure by adding a logical
173 * interface.
174 */
175static int mwifiex_pcie_probe(struct pci_dev *pdev,
176 const struct pci_device_id *ent)
177{
178 struct pcie_service_card *card;
179
180 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700181 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700182
183 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000184 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700185 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700186
187 card->dev = pdev;
188
Avinash Patildd04e6a2013-02-08 18:18:06 -0800189 if (ent->driver_data) {
190 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
191 card->pcie.firmware = data->firmware;
192 card->pcie.reg = data->reg;
193 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
Amitkumar Karwar828cf222014-02-27 19:35:13 -0800194 card->pcie.tx_buf_size = data->tx_buf_size;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800195 }
196
Amitkumar Karward930fae2011-10-11 17:41:21 -0700197 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
198 MWIFIEX_PCIE)) {
199 pr_err("%s failed\n", __func__);
200 kfree(card);
201 return -1;
202 }
203
204 return 0;
205}
206
207/*
208 * This function removes the interface and frees up the card structure.
209 */
210static void mwifiex_pcie_remove(struct pci_dev *pdev)
211{
212 struct pcie_service_card *card;
213 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700214 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700215
216 card = pci_get_drvdata(pdev);
217 if (!card)
218 return;
219
220 adapter = card->adapter;
221 if (!adapter || !adapter->priv_num)
222 return;
223
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700224 /* In case driver is removed when asynchronous FW load is in progress */
225 wait_for_completion(&adapter->fw_load);
226
Amitkumar Karward930fae2011-10-11 17:41:21 -0700227 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600228#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700229 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600230 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700231#endif
232
Amitkumar Karwar848819f2014-02-27 19:35:17 -0800233 mwifiex_deauthenticate_all(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700234
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700235 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700236
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700237 mwifiex_disable_auto_ds(priv);
238
239 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700240 }
241
242 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700243}
244
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700245static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
246{
247 user_rmmod = 1;
248 mwifiex_pcie_remove(pdev);
249
250 return;
251}
252
Amitkumar Karward930fae2011-10-11 17:41:21 -0700253static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
254 {
255 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
256 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800257 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700258 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800259 {
260 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
261 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
262 .driver_data = (unsigned long) &mwifiex_pcie8897,
263 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700264 {},
265};
266
267MODULE_DEVICE_TABLE(pci, mwifiex_ids);
268
Shuah Khan3266d732013-07-03 10:47:10 -0600269#ifdef CONFIG_PM_SLEEP
270/* Power Management Hooks */
271static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
272 mwifiex_pcie_resume);
273#endif
274
Amitkumar Karward930fae2011-10-11 17:41:21 -0700275/* PCI Device Driver */
276static struct pci_driver __refdata mwifiex_pcie = {
277 .name = "mwifiex_pcie",
278 .id_table = mwifiex_ids,
279 .probe = mwifiex_pcie_probe,
280 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600281#ifdef CONFIG_PM_SLEEP
282 .driver = {
283 .pm = &mwifiex_pcie_pm_ops,
284 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700285#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700286 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700287};
288
289/*
290 * This function writes data into PCIE card register.
291 */
292static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
293{
294 struct pcie_service_card *card = adapter->card;
295
296 iowrite32(data, card->pci_mmap1 + reg);
297
298 return 0;
299}
300
301/*
302 * This function reads data from PCIE card register.
303 */
304static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
305{
306 struct pcie_service_card *card = adapter->card;
307
308 *data = ioread32(card->pci_mmap1 + reg);
309
310 return 0;
311}
312
313/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700314 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700315 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700316static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700317{
318 int i = 0;
319
Avinash Patilc0880a22013-03-22 21:49:07 -0700320 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700321 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700322 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700323 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800324 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700325 break;
326 }
327
Avinash Patilc0880a22013-03-22 21:49:07 -0700328 return;
329}
330
Avinash Patilc4bc9802014-03-18 22:19:17 -0700331static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
332 u32 max_delay_loop_cnt)
333{
334 struct pcie_service_card *card = adapter->card;
335 u8 *buffer;
336 u32 sleep_cookie, count;
337
338 for (count = 0; count < max_delay_loop_cnt; count++) {
339 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
340 sleep_cookie = *(u32 *)buffer;
341
342 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
343 dev_dbg(adapter->dev,
344 "sleep cookie found at count %d\n", count);
345 break;
346 }
347 usleep_range(20, 30);
348 }
349
350 if (count >= max_delay_loop_cnt)
351 dev_dbg(adapter->dev,
352 "max count reached while accessing sleep cookie\n");
353}
354
Avinash Patilc0880a22013-03-22 21:49:07 -0700355/* This function wakes up the card by reading fw_status register. */
356static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
357{
358 u32 fw_status;
359 struct pcie_service_card *card = adapter->card;
360 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
361
Amitkumar Karward930fae2011-10-11 17:41:21 -0700362 dev_dbg(adapter->dev, "event: Wakeup device...\n");
363
Avinash Patilc0880a22013-03-22 21:49:07 -0700364 if (reg->sleep_cookie)
365 mwifiex_pcie_dev_wakeup_delay(adapter);
366
367 /* Reading fw_status register will wakeup device */
368 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
369 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700370 return -1;
371 }
372
Avinash Patilc0880a22013-03-22 21:49:07 -0700373 if (reg->sleep_cookie) {
374 mwifiex_pcie_dev_wakeup_delay(adapter);
375 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
376 adapter->ps_state = PS_STATE_AWAKE;
377 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700378
379 return 0;
380}
381
382/*
383 * This function is called after the card has woken up.
384 *
385 * The card configuration register is reset.
386 */
387static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
388{
389 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
390
391 return 0;
392}
393
394/*
395 * This function disables the host interrupt.
396 *
397 * The host interrupt mask is read, the disable bit is reset and
398 * written back to the card host interrupt mask register.
399 */
400static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
401{
402 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
403 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
404 0x00000000)) {
405 dev_warn(adapter->dev, "Disable host interrupt failed\n");
406 return -1;
407 }
408 }
409
410 return 0;
411}
412
413/*
414 * This function enables the host interrupt.
415 *
416 * The host interrupt enable mask is written to the card
417 * host interrupt mask register.
418 */
419static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
420{
421 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
422 /* Simply write the mask to the register */
423 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
424 HOST_INTR_MASK)) {
425 dev_warn(adapter->dev, "Enable host interrupt failed\n");
426 return -1;
427 }
428 }
429
430 return 0;
431}
432
433/*
Avinash Patil07324842013-02-08 18:18:07 -0800434 * This function initializes TX buffer ring descriptors
435 */
436static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
437{
438 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800439 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800440 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800441 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800442 int i;
443
444 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
445 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800446 if (reg->pfu_enabled) {
447 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
448 (sizeof(*desc2) * i);
449 desc2 = card->txbd_ring[i];
450 memset(desc2, 0, sizeof(*desc2));
451 } else {
452 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
453 (sizeof(*desc) * i);
454 desc = card->txbd_ring[i];
455 memset(desc, 0, sizeof(*desc));
456 }
Avinash Patil07324842013-02-08 18:18:07 -0800457 }
458
459 return 0;
460}
461
462/* This function initializes RX buffer ring descriptors. Each SKB is allocated
463 * here and after mapping PCI memory, its physical address is assigned to
464 * PCIE Rx buffer descriptor's physical address.
465 */
466static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
467{
468 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800469 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800470 struct sk_buff *skb;
471 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800472 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800473 dma_addr_t buf_pa;
474 int i;
475
476 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
477 /* Allocate skb here so that firmware can DMA data from it */
478 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
479 if (!skb) {
480 dev_err(adapter->dev,
481 "Unable to allocate skb for RX ring.\n");
482 kfree(card->rxbd_ring_vbase);
483 return -ENOMEM;
484 }
485
486 if (mwifiex_map_pci_memory(adapter, skb,
487 MWIFIEX_RX_DATA_BUF_SIZE,
488 PCI_DMA_FROMDEVICE))
489 return -1;
490
Aaron Durbindbccc922014-02-07 16:25:50 -0800491 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800492
493 dev_dbg(adapter->dev,
494 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
495 skb, skb->len, skb->data, (u32)buf_pa,
496 (u32)((u64)buf_pa >> 32));
497
498 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800499 if (reg->pfu_enabled) {
500 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
501 (sizeof(*desc2) * i);
502 desc2 = card->rxbd_ring[i];
503 desc2->paddr = buf_pa;
504 desc2->len = (u16)skb->len;
505 desc2->frag_len = (u16)skb->len;
506 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
507 desc2->offset = 0;
508 } else {
509 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
510 (sizeof(*desc) * i));
511 desc = card->rxbd_ring[i];
512 desc->paddr = buf_pa;
513 desc->len = (u16)skb->len;
514 desc->flags = 0;
515 }
Avinash Patil07324842013-02-08 18:18:07 -0800516 }
517
518 return 0;
519}
520
521/* This function initializes event buffer ring descriptors. Each SKB is
522 * allocated here and after mapping PCI memory, its physical address is assigned
523 * to PCIE Rx buffer descriptor's physical address
524 */
525static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
526{
527 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800528 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800529 struct sk_buff *skb;
530 dma_addr_t buf_pa;
531 int i;
532
533 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
534 /* Allocate skb here so that firmware can DMA data from it */
535 skb = dev_alloc_skb(MAX_EVENT_SIZE);
536 if (!skb) {
537 dev_err(adapter->dev,
538 "Unable to allocate skb for EVENT buf.\n");
539 kfree(card->evtbd_ring_vbase);
540 return -ENOMEM;
541 }
542 skb_put(skb, MAX_EVENT_SIZE);
543
544 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
545 PCI_DMA_FROMDEVICE))
546 return -1;
547
Aaron Durbindbccc922014-02-07 16:25:50 -0800548 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800549
550 dev_dbg(adapter->dev,
551 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
552 skb, skb->len, skb->data, (u32)buf_pa,
553 (u32)((u64)buf_pa >> 32));
554
555 card->evt_buf_list[i] = skb;
556 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
557 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800558 desc = card->evtbd_ring[i];
559 desc->paddr = buf_pa;
560 desc->len = (u16)skb->len;
561 desc->flags = 0;
562 }
563
564 return 0;
565}
566
567/* This function cleans up TX buffer rings. If any of the buffer list has valid
568 * SKB address, associated SKB is freed.
569 */
570static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
571{
572 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800573 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800574 struct sk_buff *skb;
575 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800576 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800577 int i;
578
579 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800580 if (reg->pfu_enabled) {
581 desc2 = card->txbd_ring[i];
582 if (card->tx_buf_list[i]) {
583 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800584 mwifiex_unmap_pci_memory(adapter, skb,
585 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800586 dev_kfree_skb_any(skb);
587 }
588 memset(desc2, 0, sizeof(*desc2));
589 } else {
590 desc = card->txbd_ring[i];
591 if (card->tx_buf_list[i]) {
592 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800593 mwifiex_unmap_pci_memory(adapter, skb,
594 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800595 dev_kfree_skb_any(skb);
596 }
597 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800598 }
599 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800600 }
601
602 return;
603}
604
605/* This function cleans up RX buffer rings. If any of the buffer list has valid
606 * SKB address, associated SKB is freed.
607 */
608static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
609{
610 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800611 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800612 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800613 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800614 struct sk_buff *skb;
615 int i;
616
617 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800618 if (reg->pfu_enabled) {
619 desc2 = card->rxbd_ring[i];
620 if (card->rx_buf_list[i]) {
621 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800622 mwifiex_unmap_pci_memory(adapter, skb,
623 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800624 dev_kfree_skb_any(skb);
625 }
626 memset(desc2, 0, sizeof(*desc2));
627 } else {
628 desc = card->rxbd_ring[i];
629 if (card->rx_buf_list[i]) {
630 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800631 mwifiex_unmap_pci_memory(adapter, skb,
632 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800633 dev_kfree_skb_any(skb);
634 }
635 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800636 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800637 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800638 }
639
640 return;
641}
642
643/* This function cleans up event buffer rings. If any of the buffer list has
644 * valid SKB address, associated SKB is freed.
645 */
646static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
647{
648 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800649 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800650 struct sk_buff *skb;
651 int i;
652
653 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
654 desc = card->evtbd_ring[i];
655 if (card->evt_buf_list[i]) {
656 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800657 mwifiex_unmap_pci_memory(adapter, skb,
658 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800659 dev_kfree_skb_any(skb);
660 }
661 card->evt_buf_list[i] = NULL;
662 memset(desc, 0, sizeof(*desc));
663 }
664
665 return;
666}
667
668/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700669 */
670static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
671{
672 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800673 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700674
675 /*
676 * driver maintaines the write pointer and firmware maintaines the read
677 * pointer. The write pointer starts at 0 (zero) while the read pointer
678 * starts at zero with rollover bit set
679 */
680 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800681
682 if (reg->pfu_enabled)
683 card->txbd_rdptr = 0;
684 else
685 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700686
687 /* allocate shared memory for the BD ring and divide the same in to
688 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800689 if (reg->pfu_enabled)
690 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
691 MWIFIEX_MAX_TXRX_BD;
692 else
693 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
694 MWIFIEX_MAX_TXRX_BD;
695
Amitkumar Karward930fae2011-10-11 17:41:21 -0700696 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700697 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800698 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
699 card->txbd_ring_size,
700 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700701 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800702 dev_err(adapter->dev,
703 "allocate consistent memory (%d bytes) failed!\n",
704 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800705 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700706 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700707 dev_dbg(adapter->dev,
708 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800709 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700710 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700711
Avinash Patil07324842013-02-08 18:18:07 -0800712 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700713}
714
715static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
716{
717 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800718 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700719
Avinash Patil07324842013-02-08 18:18:07 -0800720 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700721
Avinash Patilfc331462013-01-03 21:21:30 -0800722 if (card->txbd_ring_vbase)
723 pci_free_consistent(card->dev, card->txbd_ring_size,
724 card->txbd_ring_vbase,
725 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700726 card->txbd_ring_size = 0;
727 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800728 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700729 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800730 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700731
732 return 0;
733}
734
735/*
736 * This function creates buffer descriptor ring for RX
737 */
738static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
739{
740 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800741 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700742
743 /*
744 * driver maintaines the read pointer and firmware maintaines the write
745 * pointer. The write pointer starts at 0 (zero) while the read pointer
746 * starts at zero with rollover bit set
747 */
748 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800749 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700750
Avinash Patilca8f2112013-02-08 18:18:09 -0800751 if (reg->pfu_enabled)
752 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
753 MWIFIEX_MAX_TXRX_BD;
754 else
755 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
756 MWIFIEX_MAX_TXRX_BD;
757
Amitkumar Karward930fae2011-10-11 17:41:21 -0700758 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700759 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800760 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
761 card->rxbd_ring_size,
762 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700763 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800764 dev_err(adapter->dev,
765 "allocate consistent memory (%d bytes) failed!\n",
766 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800767 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700768 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700769
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700770 dev_dbg(adapter->dev,
771 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
772 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
773 (u32)((u64)card->rxbd_ring_pbase >> 32),
774 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700775
Avinash Patil07324842013-02-08 18:18:07 -0800776 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700777}
778
779/*
780 * This function deletes Buffer descriptor ring for RX
781 */
782static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
783{
784 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800785 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700786
Avinash Patil07324842013-02-08 18:18:07 -0800787 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700788
Avinash Patilfc331462013-01-03 21:21:30 -0800789 if (card->rxbd_ring_vbase)
790 pci_free_consistent(card->dev, card->rxbd_ring_size,
791 card->rxbd_ring_vbase,
792 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700793 card->rxbd_ring_size = 0;
794 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800795 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700796 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800797 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700798
799 return 0;
800}
801
802/*
803 * This function creates buffer descriptor ring for Events
804 */
805static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
806{
807 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800808 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700809
810 /*
811 * driver maintaines the read pointer and firmware maintaines the write
812 * pointer. The write pointer starts at 0 (zero) while the read pointer
813 * starts at zero with rollover bit set
814 */
815 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800816 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700817
Avinash Patile05dc3e2013-02-08 18:18:08 -0800818 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800819 MWIFIEX_MAX_EVT_BD;
820
Amitkumar Karward930fae2011-10-11 17:41:21 -0700821 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700822 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800823 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
824 card->evtbd_ring_size,
825 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700826 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700827 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800828 "allocate consistent memory (%d bytes) failed!\n",
829 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800830 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700831 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700832
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700833 dev_dbg(adapter->dev,
834 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
835 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
836 (u32)((u64)card->evtbd_ring_pbase >> 32),
837 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700838
Avinash Patil07324842013-02-08 18:18:07 -0800839 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700840}
841
842/*
843 * This function deletes Buffer descriptor ring for Events
844 */
845static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
846{
847 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800848 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700849
Avinash Patil07324842013-02-08 18:18:07 -0800850 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700851
Avinash Patilfc331462013-01-03 21:21:30 -0800852 if (card->evtbd_ring_vbase)
853 pci_free_consistent(card->dev, card->evtbd_ring_size,
854 card->evtbd_ring_vbase,
855 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700856 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800857 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700858 card->evtbd_ring_size = 0;
859 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800860 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700861
862 return 0;
863}
864
865/*
866 * This function allocates a buffer for CMDRSP
867 */
868static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
869{
870 struct pcie_service_card *card = adapter->card;
871 struct sk_buff *skb;
872
873 /* Allocate memory for receiving command response data */
874 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
875 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700876 dev_err(adapter->dev,
877 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700878 return -ENOMEM;
879 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700880 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800881 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
882 PCI_DMA_FROMDEVICE))
883 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700884
Avinash Patilfc331462013-01-03 21:21:30 -0800885 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700886
887 return 0;
888}
889
890/*
891 * This function deletes a buffer for CMDRSP
892 */
893static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
894{
895 struct pcie_service_card *card;
896
897 if (!adapter)
898 return 0;
899
900 card = adapter->card;
901
Avinash Patilfc331462013-01-03 21:21:30 -0800902 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800903 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
904 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700905 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800906 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700907
Avinash Patilfc331462013-01-03 21:21:30 -0800908 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800909 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
910 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800911 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700912 return 0;
913}
914
915/*
916 * This function allocates a buffer for sleep cookie
917 */
918static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
919{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700920 struct pcie_service_card *card = adapter->card;
921
Avinash Patilfc331462013-01-03 21:21:30 -0800922 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
923 &card->sleep_cookie_pbase);
924 if (!card->sleep_cookie_vbase) {
925 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700926 return -ENOMEM;
927 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700928 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800929 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700930
931 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800932 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700933
934 return 0;
935}
936
937/*
938 * This function deletes buffer for sleep cookie
939 */
940static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
941{
942 struct pcie_service_card *card;
943
944 if (!adapter)
945 return 0;
946
947 card = adapter->card;
948
Avinash Patilfc331462013-01-03 21:21:30 -0800949 if (card && card->sleep_cookie_vbase) {
950 pci_free_consistent(card->dev, sizeof(u32),
951 card->sleep_cookie_vbase,
952 card->sleep_cookie_pbase);
953 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700954 }
955
956 return 0;
957}
958
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800959/* This function flushes the TX buffer descriptor ring
960 * This function defined as handler is also called while cleaning TXRX
961 * during disconnect/ bss stop.
962 */
963static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
964{
965 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800966
Avinash Patil48f4d912013-02-20 21:12:58 -0800967 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800968 card->txbd_flush = 1;
969 /* write pointer already set at last send
970 * send dnld-rdy intr again, wait for completion.
971 */
972 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
973 CPU_INTR_DNLD_RDY)) {
974 dev_err(adapter->dev,
975 "failed to assert dnld-rdy interrupt.\n");
976 return -1;
977 }
978 }
979 return 0;
980}
981
Amitkumar Karward930fae2011-10-11 17:41:21 -0700982/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800983 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700984 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800985static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700986{
Avinash Patile7f767a2013-01-03 21:21:32 -0800987 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800988 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800989 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800990 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700991 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800992 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700993
994 if (!mwifiex_pcie_ok_to_access_hw(adapter))
995 mwifiex_pm_wakeup_card(adapter);
996
997 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800998 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700999 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001000 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001001 return -1;
1002 }
1003
Avinash Patile7f767a2013-01-03 21:21:32 -08001004 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
1005 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001006
Avinash Patilca8f2112013-02-08 18:18:09 -08001007 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001008 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001009 while (((card->txbd_rdptr & reg->tx_mask) !=
1010 (rdptr & reg->tx_mask)) ||
1011 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
1012 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -08001013 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
1014 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001015
1016 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -08001017
Avinash Patile7f767a2013-01-03 21:21:32 -08001018 if (skb) {
1019 dev_dbg(adapter->dev,
1020 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
1021 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -08001022 mwifiex_unmap_pci_memory(adapter, skb,
1023 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001024
1025 unmap_count++;
1026
1027 if (card->txbd_flush)
1028 mwifiex_write_data_complete(adapter, skb, 0,
1029 -1);
1030 else
1031 mwifiex_write_data_complete(adapter, skb, 0, 0);
1032 }
1033
1034 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001035
1036 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001037 desc2 = card->txbd_ring[wrdoneidx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001038 memset(desc2, 0, sizeof(*desc2));
1039 } else {
1040 desc = card->txbd_ring[wrdoneidx];
1041 memset(desc, 0, sizeof(*desc));
1042 }
1043 switch (card->dev->device) {
1044 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1045 card->txbd_rdptr++;
1046 break;
1047 case PCIE_DEVICE_ID_MARVELL_88W8897:
1048 card->txbd_rdptr += reg->ring_tx_start_ptr;
1049 break;
1050 }
1051
Avinash Patile7f767a2013-01-03 21:21:32 -08001052
Avinash Patildd04e6a2013-02-08 18:18:06 -08001053 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001054 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001055 reg->tx_rollover_ind) ^
1056 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001057 }
1058
1059 if (unmap_count)
1060 adapter->data_sent = false;
1061
1062 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001063 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001064 card->txbd_flush = 0;
1065 else
1066 mwifiex_clean_pcie_ring_buf(adapter);
1067 }
1068
1069 return 0;
1070}
1071
1072/* This function sends data buffer to device. First 4 bytes of payload
1073 * are filled with payload length and payload type. Then this payload
1074 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1075 * Download ready interrupt to FW is deffered if Tx ring is not full and
1076 * additional payload can be accomodated.
1077 */
1078static int
1079mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1080 struct mwifiex_tx_param *tx_param)
1081{
1082 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001083 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001084 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001085 int ret;
1086 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001087 struct mwifiex_pcie_buf_desc *desc = NULL;
1088 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001089 __le16 *tmp;
1090
1091 if (!(skb->data && skb->len)) {
1092 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1093 __func__, skb->data, skb->len);
1094 return -1;
1095 }
1096
1097 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1098 mwifiex_pm_wakeup_card(adapter);
1099
Avinash Patilca8f2112013-02-08 18:18:09 -08001100 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001101 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1102 card->txbd_rdptr, card->txbd_wrptr);
1103 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001104 u8 *payload;
1105
1106 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001107 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001108 tmp = (__le16 *)&payload[0];
1109 *tmp = cpu_to_le16((u16)skb->len);
1110 tmp = (__le16 *)&payload[2];
1111 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001112
Aaron Durbindbccc922014-02-07 16:25:50 -08001113 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001114 PCI_DMA_TODEVICE))
1115 return -1;
1116
Avinash Patilca8f2112013-02-08 18:18:09 -08001117 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001118 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001119 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001120
Avinash Patilca8f2112013-02-08 18:18:09 -08001121 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001122 desc2 = card->txbd_ring[wrindx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001123 desc2->paddr = buf_pa;
1124 desc2->len = (u16)skb->len;
1125 desc2->frag_len = (u16)skb->len;
1126 desc2->offset = 0;
1127 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1128 MWIFIEX_BD_FLAG_LAST_DESC;
1129 } else {
1130 desc = card->txbd_ring[wrindx];
1131 desc->paddr = buf_pa;
1132 desc->len = (u16)skb->len;
1133 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1134 MWIFIEX_BD_FLAG_LAST_DESC;
1135 }
1136
1137 switch (card->dev->device) {
1138 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1139 card->txbd_wrptr++;
1140 break;
1141 case PCIE_DEVICE_ID_MARVELL_88W8897:
1142 card->txbd_wrptr += reg->ring_tx_start_ptr;
1143 break;
1144 }
1145
1146 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001147 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001148 reg->tx_rollover_ind) ^
1149 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001150
Avinash Patilca8f2112013-02-08 18:18:09 -08001151 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001152 /* Write the TX ring write pointer in to reg->tx_wrptr */
1153 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001154 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001155 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001156 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001157 ret = -1;
1158 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001159 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001160 if ((mwifiex_pcie_txbd_not_full(card)) &&
1161 tx_param->next_pkt_len) {
1162 /* have more packets and TxBD still can hold more */
1163 dev_dbg(adapter->dev,
1164 "SEND DATA: delay dnld-rdy interrupt.\n");
1165 adapter->data_sent = false;
1166 } else {
1167 /* Send the TX ready interrupt */
1168 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1169 CPU_INTR_DNLD_RDY)) {
1170 dev_err(adapter->dev,
1171 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1172 ret = -1;
1173 goto done_unmap;
1174 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001175 }
1176 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001177 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001178 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001179 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001180 dev_dbg(adapter->dev,
1181 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001182 adapter->data_sent = true;
1183 /* Send the TX ready interrupt */
1184 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1185 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001186 dev_err(adapter->dev,
1187 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001188 return -EBUSY;
1189 }
1190
Avinash Patile7f767a2013-01-03 21:21:32 -08001191 return -EINPROGRESS;
1192done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001193 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001194 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001195 if (reg->pfu_enabled)
1196 memset(desc2, 0, sizeof(*desc2));
1197 else
1198 memset(desc, 0, sizeof(*desc));
1199
Avinash Patile7f767a2013-01-03 21:21:32 -08001200 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001201}
1202
1203/*
1204 * This function handles received buffer ring and
1205 * dispatches packets to upper
1206 */
1207static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1208{
1209 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001210 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001211 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001212 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001213 int ret = 0;
1214 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001215 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001216 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001217
Avinash Patile7f767a2013-01-03 21:21:32 -08001218 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1219 mwifiex_pm_wakeup_card(adapter);
1220
Amitkumar Karward930fae2011-10-11 17:41:21 -07001221 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001222 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001223 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001224 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001225 ret = -1;
1226 goto done;
1227 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001228 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001229
Avinash Patildd04e6a2013-02-08 18:18:06 -08001230 while (((wrptr & reg->rx_mask) !=
1231 (card->rxbd_rdptr & reg->rx_mask)) ||
1232 ((wrptr & reg->rx_rollover_ind) ==
1233 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001234 struct sk_buff *skb_data;
1235 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001236 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001237
Avinash Patildd04e6a2013-02-08 18:18:06 -08001238 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001239 skb_data = card->rx_buf_list[rd_index];
1240
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001241 /* If skb allocation was failed earlier for Rx packet,
1242 * rx_buf_list[rd_index] would have been left with a NULL.
1243 */
1244 if (!skb_data)
1245 return -ENOMEM;
1246
Aaron Durbindbccc922014-02-07 16:25:50 -08001247 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001248 card->rx_buf_list[rd_index] = NULL;
1249
Amitkumar Karward930fae2011-10-11 17:41:21 -07001250 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001251 * first 2 bytes for len, next 2 bytes is for type
1252 */
1253 pkt_len = *((__le16 *)skb_data->data);
1254 rx_len = le16_to_cpu(pkt_len);
1255 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001256 dev_dbg(adapter->dev,
1257 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1258 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001259 skb_pull(skb_data, INTF_HEADER_LEN);
1260 mwifiex_handle_rx_packet(adapter, skb_data);
1261
1262 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001263 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001264 dev_err(adapter->dev,
1265 "Unable to allocate skb.\n");
1266 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001267 }
1268
Avinash Patile7f767a2013-01-03 21:21:32 -08001269 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1270 MWIFIEX_RX_DATA_BUF_SIZE,
1271 PCI_DMA_FROMDEVICE))
1272 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001273
Aaron Durbindbccc922014-02-07 16:25:50 -08001274 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001275
1276 dev_dbg(adapter->dev,
1277 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1278 skb_tmp, rd_index);
1279 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001280
1281 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001282 desc2 = card->rxbd_ring[rd_index];
Avinash Patilca8f2112013-02-08 18:18:09 -08001283 desc2->paddr = buf_pa;
1284 desc2->len = skb_tmp->len;
1285 desc2->frag_len = skb_tmp->len;
1286 desc2->offset = 0;
1287 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1288 } else {
1289 desc = card->rxbd_ring[rd_index];
1290 desc->paddr = buf_pa;
1291 desc->len = skb_tmp->len;
1292 desc->flags = 0;
1293 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001294
Avinash Patildd04e6a2013-02-08 18:18:06 -08001295 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001296 MWIFIEX_MAX_TXRX_BD) {
1297 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001298 reg->rx_rollover_ind) ^
1299 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001300 }
1301 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001302 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001303
Avinash Patilca8f2112013-02-08 18:18:09 -08001304 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001305 /* Write the RX ring read pointer in to reg->rx_rdptr */
1306 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001307 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001308 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001309 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001310 ret = -1;
1311 goto done;
1312 }
1313
1314 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001315 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001316 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001317 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001318 ret = -1;
1319 goto done;
1320 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001321 dev_dbg(adapter->dev,
1322 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001323 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001324 }
1325
1326done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001327 return ret;
1328}
1329
1330/*
1331 * This function downloads the boot command to device
1332 */
1333static int
1334mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1335{
Avinash Patilfc331462013-01-03 21:21:30 -08001336 dma_addr_t buf_pa;
1337 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001338 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001339
Avinash Patilfc331462013-01-03 21:21:30 -08001340 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001341 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001342 "Invalid parameter in %s <%p. len %d>\n",
1343 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001344 return -1;
1345 }
1346
Avinash Patilfc331462013-01-03 21:21:30 -08001347 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1348 return -1;
1349
Aaron Durbindbccc922014-02-07 16:25:50 -08001350 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001351
Avinash Patildd04e6a2013-02-08 18:18:06 -08001352 /* Write the lower 32bits of the physical address to low command
1353 * address scratch register
1354 */
1355 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001356 dev_err(adapter->dev,
1357 "%s: failed to write download command to boot code.\n",
1358 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001359 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001360 return -1;
1361 }
1362
Avinash Patildd04e6a2013-02-08 18:18:06 -08001363 /* Write the upper 32bits of the physical address to high command
1364 * address scratch register
1365 */
1366 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001367 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001368 dev_err(adapter->dev,
1369 "%s: failed to write download command to boot code.\n",
1370 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001371 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001372 return -1;
1373 }
1374
Avinash Patildd04e6a2013-02-08 18:18:06 -08001375 /* Write the command length to cmd_size scratch register */
1376 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001377 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001378 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001379 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001380 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001381 return -1;
1382 }
1383
1384 /* Ring the door bell */
1385 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1386 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001387 dev_err(adapter->dev,
1388 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001389 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001390 return -1;
1391 }
1392
1393 return 0;
1394}
1395
Avinash Patilc6d1d872013-01-03 21:21:29 -08001396/* This function init rx port in firmware which in turn enables to receive data
1397 * from device before transmitting any packet.
1398 */
1399static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1400{
1401 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001402 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001403 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001404
Avinash Patildd04e6a2013-02-08 18:18:06 -08001405 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001406 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1407 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001408 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001409 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001410 return -1;
1411 }
1412 return 0;
1413}
1414
1415/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001416 */
1417static int
1418mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1419{
1420 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001421 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001422 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001423 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1424 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001425
1426 if (!(skb->data && skb->len)) {
1427 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001428 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001429 return -1;
1430 }
1431
1432 /* Make sure a command response buffer is available */
1433 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001434 dev_err(adapter->dev,
1435 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001436 return -EBUSY;
1437 }
1438
Avinash Patilfc331462013-01-03 21:21:30 -08001439 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1440 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001441
1442 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001443
1444 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1445 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1446
1447 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1448 return -1;
1449
1450 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001451
1452 /* To send a command, the driver will:
1453 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001454 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001455 2. Ring the door bell (i.e. set the door bell interrupt)
1456
1457 In response to door bell interrupt, the firmware will perform
1458 the DMA of the command packet (first header to obtain the total
1459 length and then rest of the command).
1460 */
1461
1462 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001463 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001464 /* Write the lower 32bits of the cmdrsp buffer physical
1465 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001466 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001467 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001468 dev_err(adapter->dev,
1469 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001470 ret = -1;
1471 goto done;
1472 }
1473 /* Write the upper 32bits of the cmdrsp buffer physical
1474 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001475 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001476 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001477 dev_err(adapter->dev,
1478 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001479 ret = -1;
1480 goto done;
1481 }
1482 }
1483
Aaron Durbindbccc922014-02-07 16:25:50 -08001484 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001485 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1486 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1487 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001488 dev_err(adapter->dev,
1489 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001490 ret = -1;
1491 goto done;
1492 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001493 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1494 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001495 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001496 dev_err(adapter->dev,
1497 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001498 ret = -1;
1499 goto done;
1500 }
1501
Avinash Patildd04e6a2013-02-08 18:18:06 -08001502 /* Write the command length to reg->cmd_size */
1503 if (mwifiex_write_reg(adapter, reg->cmd_size,
1504 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001505 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001506 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001507 ret = -1;
1508 goto done;
1509 }
1510
1511 /* Ring the door bell */
1512 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1513 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001514 dev_err(adapter->dev,
1515 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001516 ret = -1;
1517 goto done;
1518 }
1519
1520done:
1521 if (ret)
1522 adapter->cmd_sent = false;
1523
1524 return 0;
1525}
1526
1527/*
1528 * This function handles command complete interrupt
1529 */
1530static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1531{
1532 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001533 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001534 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001535 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001536 u16 rx_len;
1537 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001538
1539 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1540
Aaron Durbindbccc922014-02-07 16:25:50 -08001541 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001542
Aaron Durbin189b3292014-02-07 16:25:51 -08001543 /* Unmap the command as a response has been received. */
1544 if (card->cmd_buf) {
1545 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1546 PCI_DMA_TODEVICE);
1547 card->cmd_buf = NULL;
1548 }
1549
Avinash Patilfc331462013-01-03 21:21:30 -08001550 pkt_len = *((__le16 *)skb->data);
1551 rx_len = le16_to_cpu(pkt_len);
1552 skb_trim(skb, rx_len);
1553 skb_pull(skb, INTF_HEADER_LEN);
1554
Amitkumar Karward930fae2011-10-11 17:41:21 -07001555 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001556 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001557 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1558 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001559 mwifiex_pcie_enable_host_int(adapter);
1560 if (mwifiex_write_reg(adapter,
1561 PCIE_CPU_INT_EVENT,
1562 CPU_INTR_SLEEP_CFM_DONE)) {
1563 dev_warn(adapter->dev,
1564 "Write register failed\n");
1565 return -1;
1566 }
Avinash Patilc4bc9802014-03-18 22:19:17 -07001567 mwifiex_delay_for_sleep_cookie(adapter,
1568 MWIFIEX_MAX_DELAY_COUNT);
Avinash Patil52301a82013-02-12 14:38:32 -08001569 while (reg->sleep_cookie && (count++ < 10) &&
1570 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001571 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001572 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001573 dev_err(adapter->dev,
1574 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001575 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001576 memcpy(adapter->upld_buf, skb->data,
1577 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001578 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001579 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1580 PCI_DMA_FROMDEVICE))
1581 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001582 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001583 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001584 adapter->cmd_resp_received = true;
1585 /* Take the pointer and set it to CMD node and will
1586 return in the response complete callback */
1587 card->cmdrsp_buf = NULL;
1588
1589 /* Clear the cmd-rsp buffer address in scratch registers. This
1590 will prevent firmware from writing to the same response
1591 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001592 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001593 dev_err(adapter->dev,
1594 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001595 return -1;
1596 }
1597 /* Write the upper 32bits of the cmdrsp buffer physical
1598 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001599 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001600 dev_err(adapter->dev,
1601 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001602 return -1;
1603 }
1604 }
1605
1606 return 0;
1607}
1608
1609/*
1610 * Command Response processing complete handler
1611 */
1612static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1613 struct sk_buff *skb)
1614{
1615 struct pcie_service_card *card = adapter->card;
1616
1617 if (skb) {
1618 card->cmdrsp_buf = skb;
1619 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001620 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1621 PCI_DMA_FROMDEVICE))
1622 return -1;
1623 }
1624
Amitkumar Karward930fae2011-10-11 17:41:21 -07001625 return 0;
1626}
1627
1628/*
1629 * This function handles firmware event ready interrupt
1630 */
1631static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1632{
1633 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001634 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001635 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1636 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001637 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001638
1639 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1640 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001641
1642 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001643 dev_dbg(adapter->dev, "info: Event being processed, "
1644 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001645 return 0;
1646 }
1647
1648 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1649 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1650 return -1;
1651 }
1652
1653 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001654 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001655 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001656 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001657 return -1;
1658 }
1659
1660 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001661 card->evtbd_rdptr, wrptr);
1662 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1663 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001664 ((wrptr & reg->evt_rollover_ind) ==
1665 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001666 struct sk_buff *skb_cmd;
1667 __le16 data_len = 0;
1668 u16 evt_len;
1669
1670 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1671 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001672 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001673
Amitkumar Karward930fae2011-10-11 17:41:21 -07001674 /* Take the pointer and set it to event pointer in adapter
1675 and will return back after event handling callback */
1676 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001677 desc = card->evtbd_ring[rdptr];
1678 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001679
1680 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1681 adapter->event_cause = event;
1682 /* The first 4bytes will be the event transfer header
1683 len is 2 bytes followed by type which is 2 bytes */
1684 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1685 evt_len = le16_to_cpu(data_len);
1686
1687 skb_pull(skb_cmd, INTF_HEADER_LEN);
1688 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1689
1690 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1691 memcpy(adapter->event_body, skb_cmd->data +
1692 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1693 MWIFIEX_EVENT_HEADER_LEN);
1694
1695 adapter->event_received = true;
1696 adapter->event_skb = skb_cmd;
1697
1698 /* Do not update the event read pointer here, wait till the
1699 buffer is released. This is just to make things simpler,
1700 we need to find a better method of managing these buffers.
1701 */
1702 }
1703
1704 return 0;
1705}
1706
1707/*
1708 * Event processing complete handler
1709 */
1710static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1711 struct sk_buff *skb)
1712{
1713 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001714 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001715 int ret = 0;
1716 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1717 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001718 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001719
1720 if (!skb)
1721 return 0;
1722
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001723 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001724 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001725 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001726 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001727 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001728
1729 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001730 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001731 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001732 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001733 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001734 }
1735
1736 if (!card->evt_buf_list[rdptr]) {
1737 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001738 if (mwifiex_map_pci_memory(adapter, skb,
1739 MAX_EVENT_SIZE,
1740 PCI_DMA_FROMDEVICE))
1741 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001742 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001743 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001744 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001745 desc->len = (u16)skb->len;
1746 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001747 skb = NULL;
1748 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001749 dev_dbg(adapter->dev,
1750 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1751 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001752 }
1753
1754 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1755 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001756 reg->evt_rollover_ind) ^
1757 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001758 }
1759
1760 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001761 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001762
Avinash Patildd04e6a2013-02-08 18:18:06 -08001763 /* Write the event ring read pointer in to reg->evt_rdptr */
1764 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1765 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001766 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001767 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001768 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001769 }
1770
Amitkumar Karward930fae2011-10-11 17:41:21 -07001771 dev_dbg(adapter->dev, "info: Check Events Again\n");
1772 ret = mwifiex_pcie_process_event_ready(adapter);
1773
1774 return ret;
1775}
1776
1777/*
1778 * This function downloads the firmware to the card.
1779 *
1780 * Firmware is downloaded to the card in blocks. Every block download
1781 * is tested for CRC errors, and retried a number of times before
1782 * returning failure.
1783 */
1784static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1785 struct mwifiex_fw_image *fw)
1786{
1787 int ret;
1788 u8 *firmware = fw->fw_buf;
1789 u32 firmware_len = fw->fw_len;
1790 u32 offset = 0;
1791 struct sk_buff *skb;
1792 u32 txlen, tx_blocks = 0, tries, len;
1793 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001794 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001795 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001796
1797 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001798 dev_err(adapter->dev,
1799 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001800 return -1;
1801 }
1802
1803 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001804 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001805
1806 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001807 dev_err(adapter->dev,
1808 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001809 return -1;
1810 }
1811
1812 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1813 if (!skb) {
1814 ret = -ENOMEM;
1815 goto done;
1816 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001817
1818 /* Perform firmware data transfer */
1819 do {
1820 u32 ireg_intr = 0;
1821
1822 /* More data? */
1823 if (offset >= firmware_len)
1824 break;
1825
1826 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001827 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001828 &len);
1829 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001830 dev_warn(adapter->dev,
1831 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001832 goto done;
1833 }
1834 if (len)
1835 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001836 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001837 }
1838
1839 if (!len) {
1840 break;
1841 } else if (len > MWIFIEX_UPLD_SIZE) {
1842 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001843 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001844 ret = -1;
1845 goto done;
1846 }
1847
1848 txlen = len;
1849
1850 if (len & BIT(0)) {
1851 block_retry_cnt++;
1852 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1853 pr_err("FW download failure @ %d, over max "
1854 "retry count\n", offset);
1855 ret = -1;
1856 goto done;
1857 }
1858 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001859 "helper: len = 0x%04X, txlen = %d\n",
1860 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001861 len &= ~BIT(0);
1862 /* Setting this to 0 to resend from same offset */
1863 txlen = 0;
1864 } else {
1865 block_retry_cnt = 0;
1866 /* Set blocksize to transfer - checking for
1867 last block */
1868 if (firmware_len - offset < txlen)
1869 txlen = firmware_len - offset;
1870
1871 dev_dbg(adapter->dev, ".");
1872
Avinash Patildd04e6a2013-02-08 18:18:06 -08001873 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1874 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001875
1876 /* Copy payload to buffer */
1877 memmove(skb->data, &firmware[offset], txlen);
1878 }
1879
1880 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001881 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001882
1883 /* Send the boot command to device */
1884 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001885 dev_err(adapter->dev,
1886 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001887 ret = -1;
1888 goto done;
1889 }
Avinash Patilfc331462013-01-03 21:21:30 -08001890
Amitkumar Karward930fae2011-10-11 17:41:21 -07001891 /* Wait for the command done interrupt */
1892 do {
1893 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1894 &ireg_intr)) {
1895 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001896 "interrupt status during fw dnld.\n",
1897 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001898 mwifiex_unmap_pci_memory(adapter, skb,
1899 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001900 ret = -1;
1901 goto done;
1902 }
1903 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1904 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001905
Aaron Durbindbccc922014-02-07 16:25:50 -08001906 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001907
Amitkumar Karward930fae2011-10-11 17:41:21 -07001908 offset += txlen;
1909 } while (true);
1910
1911 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001912 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001913
1914 ret = 0;
1915
1916done:
1917 dev_kfree_skb_any(skb);
1918 return ret;
1919}
1920
1921/*
1922 * This function checks the firmware status in card.
1923 *
1924 * The winner interface is also determined by this function.
1925 */
1926static int
1927mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1928{
1929 int ret = 0;
1930 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001931 struct pcie_service_card *card = adapter->card;
1932 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001933 u32 tries;
1934
1935 /* Mask spurios interrupts */
1936 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001937 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001938 dev_warn(adapter->dev, "Write register failed\n");
1939 return -1;
1940 }
1941
1942 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001943 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1944 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001945 dev_err(adapter->dev,
1946 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001947 return -1;
1948 }
1949
1950 /* Wait for firmware initialization event */
1951 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001952 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001953 &firmware_stat))
1954 ret = -1;
1955 else
1956 ret = 0;
1957 if (ret)
1958 continue;
1959 if (firmware_stat == FIRMWARE_READY_PCIE) {
1960 ret = 0;
1961 break;
1962 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07001963 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001964 ret = -1;
1965 }
1966 }
1967
1968 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001969 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001970 &winner_status))
1971 ret = -1;
1972 else if (!winner_status) {
1973 dev_err(adapter->dev, "PCI-E is the winner\n");
1974 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001975 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001976 dev_err(adapter->dev,
1977 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1978 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001979 }
1980 }
1981
1982 return ret;
1983}
1984
1985/*
1986 * This function reads the interrupt status from card.
1987 */
1988static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1989{
1990 u32 pcie_ireg;
1991 unsigned long flags;
1992
1993 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1994 return;
1995
1996 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1997 dev_warn(adapter->dev, "Read register failed\n");
1998 return;
1999 }
2000
2001 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2002
2003 mwifiex_pcie_disable_host_int(adapter);
2004
2005 /* Clear the pending interrupts */
2006 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2007 ~pcie_ireg)) {
2008 dev_warn(adapter->dev, "Write register failed\n");
2009 return;
2010 }
2011 spin_lock_irqsave(&adapter->int_lock, flags);
2012 adapter->int_status |= pcie_ireg;
2013 spin_unlock_irqrestore(&adapter->int_lock, flags);
2014
Amitkumar Karwar1c975602014-02-18 15:41:56 -08002015 if (!adapter->pps_uapsd_mode &&
2016 adapter->ps_state == PS_STATE_SLEEP &&
2017 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002018 /* Potentially for PCIe we could get other
2019 * interrupts like shared. Don't change power
2020 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002021 adapter->ps_state = PS_STATE_AWAKE;
2022 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002023 }
2024 }
2025}
2026
2027/*
2028 * Interrupt handler for PCIe root port
2029 *
2030 * This function reads the interrupt status from firmware and assigns
2031 * the main process in workqueue which will handle the interrupt.
2032 */
2033static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2034{
2035 struct pci_dev *pdev = (struct pci_dev *)context;
2036 struct pcie_service_card *card;
2037 struct mwifiex_adapter *adapter;
2038
2039 if (!pdev) {
2040 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2041 goto exit;
2042 }
2043
Jingoo Hanb2a31202013-09-09 14:26:51 +09002044 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002045 if (!card || !card->adapter) {
2046 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002047 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002048 goto exit;
2049 }
2050 adapter = card->adapter;
2051
2052 if (adapter->surprise_removed)
2053 goto exit;
2054
2055 mwifiex_interrupt_status(adapter);
2056 queue_work(adapter->workqueue, &adapter->main_work);
2057
2058exit:
2059 return IRQ_HANDLED;
2060}
2061
2062/*
2063 * This function checks the current interrupt status.
2064 *
2065 * The following interrupts are checked and handled by this function -
2066 * - Data sent
2067 * - Command sent
2068 * - Command received
2069 * - Packets received
2070 * - Events received
2071 *
2072 * In case of Rx packets received, the packets are uploaded from card to
2073 * host and processed accordingly.
2074 */
2075static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2076{
2077 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002078 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002079 unsigned long flags;
2080
2081 spin_lock_irqsave(&adapter->int_lock, flags);
2082 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002083 pcie_ireg = adapter->int_status;
2084 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002085 spin_unlock_irqrestore(&adapter->int_lock, flags);
2086
Avinash Patil659c4782013-01-03 21:21:28 -08002087 while (pcie_ireg & HOST_INTR_MASK) {
2088 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2089 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002090 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2091 ret = mwifiex_pcie_send_data_complete(adapter);
2092 if (ret)
2093 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002094 }
Avinash Patil659c4782013-01-03 21:21:28 -08002095 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2096 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002097 dev_dbg(adapter->dev, "info: Rx DATA\n");
2098 ret = mwifiex_pcie_process_recv_data(adapter);
2099 if (ret)
2100 return ret;
2101 }
Avinash Patil659c4782013-01-03 21:21:28 -08002102 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2103 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002104 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2105 ret = mwifiex_pcie_process_event_ready(adapter);
2106 if (ret)
2107 return ret;
2108 }
2109
Avinash Patil659c4782013-01-03 21:21:28 -08002110 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2111 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002112 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002113 dev_dbg(adapter->dev,
2114 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002115 adapter->cmd_sent = false;
2116 }
2117 /* Handle command response */
2118 ret = mwifiex_pcie_process_cmd_complete(adapter);
2119 if (ret)
2120 return ret;
2121 }
2122
2123 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2124 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2125 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002126 dev_warn(adapter->dev,
2127 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002128 return -1;
2129 }
2130
2131 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2132 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002133 PCIE_HOST_INT_STATUS,
2134 ~pcie_ireg)) {
2135 dev_warn(adapter->dev,
2136 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002137 return -1;
2138 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002139 }
2140
2141 }
2142 }
2143 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002144 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002145 if (adapter->ps_state != PS_STATE_SLEEP)
2146 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002147
2148 return 0;
2149}
2150
2151/*
2152 * This function downloads data from driver to card.
2153 *
2154 * Both commands and data packets are transferred to the card by this
2155 * function.
2156 *
2157 * This function adds the PCIE specific header to the front of the buffer
2158 * before transferring. The header contains the length of the packet and
2159 * the type. The firmware handles the packets based upon this set type.
2160 */
2161static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2162 struct sk_buff *skb,
2163 struct mwifiex_tx_param *tx_param)
2164{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002165 if (!skb) {
2166 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002167 return -1;
2168 }
2169
2170 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002171 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002172 else if (type == MWIFIEX_TYPE_CMD)
2173 return mwifiex_pcie_send_cmd(adapter, skb);
2174
2175 return 0;
2176}
2177
2178/*
2179 * This function initializes the PCI-E host memory space, WCB rings, etc.
2180 *
2181 * The following initializations steps are followed -
2182 * - Allocate TXBD ring buffers
2183 * - Allocate RXBD ring buffers
2184 * - Allocate event BD ring buffers
2185 * - Allocate command response ring buffer
2186 * - Allocate sleep cookie buffer
2187 */
2188static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2189{
2190 struct pcie_service_card *card = adapter->card;
2191 int ret;
2192 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002193 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002194
2195 pci_set_drvdata(pdev, card);
2196
2197 ret = pci_enable_device(pdev);
2198 if (ret)
2199 goto err_enable_dev;
2200
2201 pci_set_master(pdev);
2202
2203 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2204 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2205 if (ret) {
2206 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2207 goto err_set_dma_mask;
2208 }
2209
2210 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2211 if (ret) {
2212 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2213 goto err_set_dma_mask;
2214 }
2215
2216 ret = pci_request_region(pdev, 0, DRV_NAME);
2217 if (ret) {
2218 dev_err(adapter->dev, "req_reg(0) error\n");
2219 goto err_req_region0;
2220 }
2221 card->pci_mmap = pci_iomap(pdev, 0, 0);
2222 if (!card->pci_mmap) {
2223 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002224 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002225 goto err_iomap0;
2226 }
2227 ret = pci_request_region(pdev, 2, DRV_NAME);
2228 if (ret) {
2229 dev_err(adapter->dev, "req_reg(2) error\n");
2230 goto err_req_region2;
2231 }
2232 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2233 if (!card->pci_mmap1) {
2234 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002235 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002236 goto err_iomap2;
2237 }
2238
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002239 dev_dbg(adapter->dev,
2240 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2241 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002242
2243 card->cmdrsp_buf = NULL;
2244 ret = mwifiex_pcie_create_txbd_ring(adapter);
2245 if (ret)
2246 goto err_cre_txbd;
2247 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2248 if (ret)
2249 goto err_cre_rxbd;
2250 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2251 if (ret)
2252 goto err_cre_evtbd;
2253 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2254 if (ret)
2255 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002256 if (reg->sleep_cookie) {
2257 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2258 if (ret)
2259 goto err_alloc_cookie;
2260 } else {
2261 card->sleep_cookie_vbase = NULL;
2262 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002263 return ret;
2264
2265err_alloc_cookie:
2266 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2267err_alloc_cmdbuf:
2268 mwifiex_pcie_delete_evtbd_ring(adapter);
2269err_cre_evtbd:
2270 mwifiex_pcie_delete_rxbd_ring(adapter);
2271err_cre_rxbd:
2272 mwifiex_pcie_delete_txbd_ring(adapter);
2273err_cre_txbd:
2274 pci_iounmap(pdev, card->pci_mmap1);
2275err_iomap2:
2276 pci_release_region(pdev, 2);
2277err_req_region2:
2278 pci_iounmap(pdev, card->pci_mmap);
2279err_iomap0:
2280 pci_release_region(pdev, 0);
2281err_req_region0:
2282err_set_dma_mask:
2283 pci_disable_device(pdev);
2284err_enable_dev:
2285 pci_set_drvdata(pdev, NULL);
2286 return ret;
2287}
2288
2289/*
2290 * This function cleans up the allocated card buffers.
2291 *
2292 * The following are freed by this function -
2293 * - TXBD ring buffers
2294 * - RXBD ring buffers
2295 * - Event BD ring buffers
2296 * - Command response ring buffer
2297 * - Sleep cookie buffer
2298 */
2299static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2300{
2301 struct pcie_service_card *card = adapter->card;
2302 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002303 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002304
Amitkumar Karward930fae2011-10-11 17:41:21 -07002305 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002306 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002307 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002308 dev_err(adapter->dev,
2309 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002310 }
2311
2312 if (pdev) {
2313 pci_iounmap(pdev, card->pci_mmap);
2314 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002315 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002316 pci_release_region(pdev, 2);
2317 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002318 pci_set_drvdata(pdev, NULL);
2319 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002320 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002321}
2322
2323/*
2324 * This function registers the PCIE device.
2325 *
2326 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2327 */
2328static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2329{
2330 int ret;
2331 struct pcie_service_card *card = adapter->card;
2332 struct pci_dev *pdev = card->dev;
2333
2334 /* save adapter pointer in card */
2335 card->adapter = adapter;
2336
2337 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2338 "MRVL_PCIE", pdev);
2339 if (ret) {
2340 pr_err("request_irq failed: ret=%d\n", ret);
2341 adapter->card = NULL;
2342 return -1;
2343 }
2344
2345 adapter->dev = &pdev->dev;
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002346 adapter->tx_buf_size = card->pcie.tx_buf_size;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002347 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002348
2349 return 0;
2350}
2351
2352/*
2353 * This function unregisters the PCIE device.
2354 *
2355 * The PCIE IRQ is released, the function is disabled and driver
2356 * data is set to null.
2357 */
2358static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2359{
2360 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002361 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002362
2363 if (card) {
2364 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2365 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002366
Avinash Patil52301a82013-02-12 14:38:32 -08002367 reg = card->pcie.reg;
2368 if (reg->sleep_cookie)
2369 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2370
Avinash Patilfc331462013-01-03 21:21:30 -08002371 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2372 mwifiex_pcie_delete_evtbd_ring(adapter);
2373 mwifiex_pcie_delete_rxbd_ring(adapter);
2374 mwifiex_pcie_delete_txbd_ring(adapter);
2375 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002376 }
2377}
2378
2379static struct mwifiex_if_ops pcie_ops = {
2380 .init_if = mwifiex_pcie_init,
2381 .cleanup_if = mwifiex_pcie_cleanup,
2382 .check_fw_status = mwifiex_check_fw_status,
2383 .prog_fw = mwifiex_prog_fw_w_helper,
2384 .register_dev = mwifiex_register_dev,
2385 .unregister_dev = mwifiex_unregister_dev,
2386 .enable_int = mwifiex_pcie_enable_host_int,
2387 .process_int_status = mwifiex_process_int_status,
2388 .host_to_card = mwifiex_pcie_host_to_card,
2389 .wakeup = mwifiex_pm_wakeup_card,
2390 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2391
2392 /* PCIE specific */
2393 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2394 .event_complete = mwifiex_pcie_event_complete,
2395 .update_mp_end_port = NULL,
2396 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002397 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002398 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002399};
2400
2401/*
2402 * This function initializes the PCIE driver module.
2403 *
2404 * This initiates the semaphore and registers the device with
2405 * PCIE bus.
2406 */
2407static int mwifiex_pcie_init_module(void)
2408{
2409 int ret;
2410
Avinash Patilca8f2112013-02-08 18:18:09 -08002411 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002412
2413 sema_init(&add_remove_card_sem, 1);
2414
2415 /* Clear the flag in case user removes the card. */
2416 user_rmmod = 0;
2417
2418 ret = pci_register_driver(&mwifiex_pcie);
2419 if (ret)
2420 pr_err("Driver register failed!\n");
2421 else
2422 pr_debug("info: Driver registered successfully!\n");
2423
2424 return ret;
2425}
2426
2427/*
2428 * This function cleans up the PCIE driver.
2429 *
2430 * The following major steps are followed for cleanup -
2431 * - Resume the device if its suspended
2432 * - Disconnect the device if connected
2433 * - Shutdown the firmware
2434 * - Unregister the device from PCIE bus.
2435 */
2436static void mwifiex_pcie_cleanup_module(void)
2437{
2438 if (!down_interruptible(&add_remove_card_sem))
2439 up(&add_remove_card_sem);
2440
2441 /* Set the flag as user is removing this module. */
2442 user_rmmod = 1;
2443
2444 pci_unregister_driver(&mwifiex_pcie);
2445}
2446
2447module_init(mwifiex_pcie_init_module);
2448module_exit(mwifiex_pcie_cleanup_module);
2449
2450MODULE_AUTHOR("Marvell International Ltd.");
2451MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2452MODULE_VERSION(PCIE_VERSION);
2453MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002454MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2455MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);