blob: d11d4acf089022888f8996381c38bd452ae0691f [file] [log] [blame]
Amitkumar Karward930fae2011-10-11 17:41:21 -07001/*
2 * Marvell Wireless LAN device driver: PCIE specific handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/firmware.h>
21
22#include "decl.h"
23#include "ioctl.h"
24#include "util.h"
25#include "fw.h"
26#include "main.h"
27#include "wmm.h"
28#include "11n.h"
29#include "pcie.h"
30
31#define PCIE_VERSION "1.0"
32#define DRV_NAME "Marvell mwifiex PCIe"
33
34static u8 user_rmmod;
35
36static struct mwifiex_if_ops pcie_ops;
37
38static struct semaphore add_remove_card_sem;
Amitkumar Karward930fae2011-10-11 17:41:21 -070039
Avinash Patilfc331462013-01-03 21:21:30 -080040static int
41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
Aaron Durbindbccc922014-02-07 16:25:50 -080042 size_t size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070043{
Avinash Patilfc331462013-01-03 21:21:30 -080044 struct pcie_service_card *card = adapter->card;
Aaron Durbindbccc922014-02-07 16:25:50 -080045 struct mwifiex_dma_mapping mapping;
Amitkumar Karward930fae2011-10-11 17:41:21 -070046
Aaron Durbindbccc922014-02-07 16:25:50 -080047 mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
48 if (pci_dma_mapping_error(card->dev, mapping.addr)) {
Avinash Patilfc331462013-01-03 21:21:30 -080049 dev_err(adapter->dev, "failed to map pci memory!\n");
50 return -1;
51 }
Aaron Durbindbccc922014-02-07 16:25:50 -080052 mapping.len = size;
53 memcpy(skb->cb, &mapping, sizeof(mapping));
Avinash Patilfc331462013-01-03 21:21:30 -080054 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070055}
56
Aaron Durbindbccc922014-02-07 16:25:50 -080057static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
58 struct sk_buff *skb, int flags)
59{
60 struct pcie_service_card *card = adapter->card;
61 struct mwifiex_dma_mapping mapping;
62
63 MWIFIEX_SKB_PACB(skb, &mapping);
64 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
65}
66
Amitkumar Karward930fae2011-10-11 17:41:21 -070067/*
68 * This function reads sleep cookie and checks if FW is ready
69 */
70static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
71{
72 u32 *cookie_addr;
73 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080074 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
75
76 if (!reg->sleep_cookie)
77 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070078
Avinash Patilfc331462013-01-03 21:21:30 -080079 if (card->sleep_cookie_vbase) {
80 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070081 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
82 *cookie_addr);
83 if (*cookie_addr == FW_AWAKE_COOKIE)
84 return true;
85 }
86
87 return false;
88}
89
Shuah Khan3266d732013-07-03 10:47:10 -060090#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -070091/*
Bing Zhaofcca8d52013-03-04 16:27:53 -080092 * Kernel needs to suspend all functions separately. Therefore all
93 * registered functions must have drivers with suspend and resume
94 * methods. Failing that the kernel simply removes the whole card.
95 *
96 * If already not suspended, this function allocates and sends a host
97 * sleep activate request to the firmware and turns off the traffic.
98 */
Shuah Khan3266d732013-07-03 10:47:10 -060099static int mwifiex_pcie_suspend(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800100{
101 struct mwifiex_adapter *adapter;
102 struct pcie_service_card *card;
103 int hs_actived;
Shuah Khan3266d732013-07-03 10:47:10 -0600104 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800105
106 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900107 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800108 if (!card || !card->adapter) {
109 pr_err("Card or adapter structure is not valid\n");
110 return 0;
111 }
112 } else {
113 pr_err("PCIE device is not specified\n");
114 return 0;
115 }
116
117 adapter = card->adapter;
118
119 hs_actived = mwifiex_enable_hs(adapter);
120
121 /* Indicate device suspended */
122 adapter->is_suspended = true;
123
124 return 0;
125}
126
127/*
128 * Kernel needs to suspend all functions separately. Therefore all
129 * registered functions must have drivers with suspend and resume
130 * methods. Failing that the kernel simply removes the whole card.
131 *
132 * If already not resumed, this function turns on the traffic and
133 * sends a host sleep cancel request to the firmware.
134 */
Shuah Khan3266d732013-07-03 10:47:10 -0600135static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800136{
137 struct mwifiex_adapter *adapter;
138 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600139 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800140
141 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900142 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800143 if (!card || !card->adapter) {
144 pr_err("Card or adapter structure is not valid\n");
145 return 0;
146 }
147 } else {
148 pr_err("PCIE device is not specified\n");
149 return 0;
150 }
151
152 adapter = card->adapter;
153
154 if (!adapter->is_suspended) {
155 dev_warn(adapter->dev, "Device already resumed\n");
156 return 0;
157 }
158
159 adapter->is_suspended = false;
160
161 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
162 MWIFIEX_ASYNC_CMD);
163
164 return 0;
165}
Bing Zhao8509e822013-03-04 16:27:54 -0800166#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800167
168/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700169 * This function probes an mwifiex device and registers it. It allocates
170 * the card structure, enables PCIE function number and initiates the
171 * device registration and initialization procedure by adding a logical
172 * interface.
173 */
174static int mwifiex_pcie_probe(struct pci_dev *pdev,
175 const struct pci_device_id *ent)
176{
177 struct pcie_service_card *card;
178
179 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700180 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700181
182 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000183 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700184 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700185
186 card->dev = pdev;
187
Avinash Patildd04e6a2013-02-08 18:18:06 -0800188 if (ent->driver_data) {
189 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
190 card->pcie.firmware = data->firmware;
191 card->pcie.reg = data->reg;
192 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
193 }
194
Amitkumar Karward930fae2011-10-11 17:41:21 -0700195 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
196 MWIFIEX_PCIE)) {
197 pr_err("%s failed\n", __func__);
198 kfree(card);
199 return -1;
200 }
201
202 return 0;
203}
204
205/*
206 * This function removes the interface and frees up the card structure.
207 */
208static void mwifiex_pcie_remove(struct pci_dev *pdev)
209{
210 struct pcie_service_card *card;
211 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700212 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700213 int i;
214
215 card = pci_get_drvdata(pdev);
216 if (!card)
217 return;
218
219 adapter = card->adapter;
220 if (!adapter || !adapter->priv_num)
221 return;
222
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700223 /* In case driver is removed when asynchronous FW load is in progress */
224 wait_for_completion(&adapter->fw_load);
225
Amitkumar Karward930fae2011-10-11 17:41:21 -0700226 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600227#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700228 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600229 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700230#endif
231
232 for (i = 0; i < adapter->priv_num; i++)
233 if ((GET_BSS_ROLE(adapter->priv[i]) ==
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700234 MWIFIEX_BSS_ROLE_STA) &&
235 adapter->priv[i]->media_connected)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700236 mwifiex_deauthenticate(adapter->priv[i], NULL);
237
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700238 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700239
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700240 mwifiex_disable_auto_ds(priv);
241
242 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700243 }
244
245 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700246}
247
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700248static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
249{
250 user_rmmod = 1;
251 mwifiex_pcie_remove(pdev);
252
253 return;
254}
255
Amitkumar Karward930fae2011-10-11 17:41:21 -0700256static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
257 {
258 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
259 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800260 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700261 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800262 {
263 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
264 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
265 .driver_data = (unsigned long) &mwifiex_pcie8897,
266 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700267 {},
268};
269
270MODULE_DEVICE_TABLE(pci, mwifiex_ids);
271
Shuah Khan3266d732013-07-03 10:47:10 -0600272#ifdef CONFIG_PM_SLEEP
273/* Power Management Hooks */
274static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
275 mwifiex_pcie_resume);
276#endif
277
Amitkumar Karward930fae2011-10-11 17:41:21 -0700278/* PCI Device Driver */
279static struct pci_driver __refdata mwifiex_pcie = {
280 .name = "mwifiex_pcie",
281 .id_table = mwifiex_ids,
282 .probe = mwifiex_pcie_probe,
283 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600284#ifdef CONFIG_PM_SLEEP
285 .driver = {
286 .pm = &mwifiex_pcie_pm_ops,
287 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700288#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700289 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700290};
291
292/*
293 * This function writes data into PCIE card register.
294 */
295static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
296{
297 struct pcie_service_card *card = adapter->card;
298
299 iowrite32(data, card->pci_mmap1 + reg);
300
301 return 0;
302}
303
304/*
305 * This function reads data from PCIE card register.
306 */
307static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
308{
309 struct pcie_service_card *card = adapter->card;
310
311 *data = ioread32(card->pci_mmap1 + reg);
312
313 return 0;
314}
315
316/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700317 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700318 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700319static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700320{
321 int i = 0;
322
Avinash Patilc0880a22013-03-22 21:49:07 -0700323 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700324 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700325 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700326 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800327 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700328 break;
329 }
330
Avinash Patilc0880a22013-03-22 21:49:07 -0700331 return;
332}
333
334/* This function wakes up the card by reading fw_status register. */
335static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
336{
337 u32 fw_status;
338 struct pcie_service_card *card = adapter->card;
339 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
340
Amitkumar Karward930fae2011-10-11 17:41:21 -0700341 dev_dbg(adapter->dev, "event: Wakeup device...\n");
342
Avinash Patilc0880a22013-03-22 21:49:07 -0700343 if (reg->sleep_cookie)
344 mwifiex_pcie_dev_wakeup_delay(adapter);
345
346 /* Reading fw_status register will wakeup device */
347 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
348 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700349 return -1;
350 }
351
Avinash Patilc0880a22013-03-22 21:49:07 -0700352 if (reg->sleep_cookie) {
353 mwifiex_pcie_dev_wakeup_delay(adapter);
354 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
355 adapter->ps_state = PS_STATE_AWAKE;
356 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700357
358 return 0;
359}
360
361/*
362 * This function is called after the card has woken up.
363 *
364 * The card configuration register is reset.
365 */
366static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
367{
368 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
369
370 return 0;
371}
372
373/*
374 * This function disables the host interrupt.
375 *
376 * The host interrupt mask is read, the disable bit is reset and
377 * written back to the card host interrupt mask register.
378 */
379static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
380{
381 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
382 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
383 0x00000000)) {
384 dev_warn(adapter->dev, "Disable host interrupt failed\n");
385 return -1;
386 }
387 }
388
389 return 0;
390}
391
392/*
393 * This function enables the host interrupt.
394 *
395 * The host interrupt enable mask is written to the card
396 * host interrupt mask register.
397 */
398static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
399{
400 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
401 /* Simply write the mask to the register */
402 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
403 HOST_INTR_MASK)) {
404 dev_warn(adapter->dev, "Enable host interrupt failed\n");
405 return -1;
406 }
407 }
408
409 return 0;
410}
411
412/*
Avinash Patil07324842013-02-08 18:18:07 -0800413 * This function initializes TX buffer ring descriptors
414 */
415static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
416{
417 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800418 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800419 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800420 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800421 int i;
422
423 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
424 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800425 if (reg->pfu_enabled) {
426 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
427 (sizeof(*desc2) * i);
428 desc2 = card->txbd_ring[i];
429 memset(desc2, 0, sizeof(*desc2));
430 } else {
431 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
432 (sizeof(*desc) * i);
433 desc = card->txbd_ring[i];
434 memset(desc, 0, sizeof(*desc));
435 }
Avinash Patil07324842013-02-08 18:18:07 -0800436 }
437
438 return 0;
439}
440
441/* This function initializes RX buffer ring descriptors. Each SKB is allocated
442 * here and after mapping PCI memory, its physical address is assigned to
443 * PCIE Rx buffer descriptor's physical address.
444 */
445static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
446{
447 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800448 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800449 struct sk_buff *skb;
450 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800451 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800452 dma_addr_t buf_pa;
453 int i;
454
455 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
456 /* Allocate skb here so that firmware can DMA data from it */
457 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
458 if (!skb) {
459 dev_err(adapter->dev,
460 "Unable to allocate skb for RX ring.\n");
461 kfree(card->rxbd_ring_vbase);
462 return -ENOMEM;
463 }
464
465 if (mwifiex_map_pci_memory(adapter, skb,
466 MWIFIEX_RX_DATA_BUF_SIZE,
467 PCI_DMA_FROMDEVICE))
468 return -1;
469
Aaron Durbindbccc922014-02-07 16:25:50 -0800470 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800471
472 dev_dbg(adapter->dev,
473 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
474 skb, skb->len, skb->data, (u32)buf_pa,
475 (u32)((u64)buf_pa >> 32));
476
477 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800478 if (reg->pfu_enabled) {
479 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
480 (sizeof(*desc2) * i);
481 desc2 = card->rxbd_ring[i];
482 desc2->paddr = buf_pa;
483 desc2->len = (u16)skb->len;
484 desc2->frag_len = (u16)skb->len;
485 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
486 desc2->offset = 0;
487 } else {
488 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
489 (sizeof(*desc) * i));
490 desc = card->rxbd_ring[i];
491 desc->paddr = buf_pa;
492 desc->len = (u16)skb->len;
493 desc->flags = 0;
494 }
Avinash Patil07324842013-02-08 18:18:07 -0800495 }
496
497 return 0;
498}
499
500/* This function initializes event buffer ring descriptors. Each SKB is
501 * allocated here and after mapping PCI memory, its physical address is assigned
502 * to PCIE Rx buffer descriptor's physical address
503 */
504static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
505{
506 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800507 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800508 struct sk_buff *skb;
509 dma_addr_t buf_pa;
510 int i;
511
512 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
513 /* Allocate skb here so that firmware can DMA data from it */
514 skb = dev_alloc_skb(MAX_EVENT_SIZE);
515 if (!skb) {
516 dev_err(adapter->dev,
517 "Unable to allocate skb for EVENT buf.\n");
518 kfree(card->evtbd_ring_vbase);
519 return -ENOMEM;
520 }
521 skb_put(skb, MAX_EVENT_SIZE);
522
523 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
524 PCI_DMA_FROMDEVICE))
525 return -1;
526
Aaron Durbindbccc922014-02-07 16:25:50 -0800527 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800528
529 dev_dbg(adapter->dev,
530 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
531 skb, skb->len, skb->data, (u32)buf_pa,
532 (u32)((u64)buf_pa >> 32));
533
534 card->evt_buf_list[i] = skb;
535 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
536 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800537 desc = card->evtbd_ring[i];
538 desc->paddr = buf_pa;
539 desc->len = (u16)skb->len;
540 desc->flags = 0;
541 }
542
543 return 0;
544}
545
546/* This function cleans up TX buffer rings. If any of the buffer list has valid
547 * SKB address, associated SKB is freed.
548 */
549static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
550{
551 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800552 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800553 struct sk_buff *skb;
554 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800555 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800556 int i;
557
558 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800559 if (reg->pfu_enabled) {
560 desc2 = card->txbd_ring[i];
561 if (card->tx_buf_list[i]) {
562 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800563 mwifiex_unmap_pci_memory(adapter, skb,
564 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800565 dev_kfree_skb_any(skb);
566 }
567 memset(desc2, 0, sizeof(*desc2));
568 } else {
569 desc = card->txbd_ring[i];
570 if (card->tx_buf_list[i]) {
571 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800572 mwifiex_unmap_pci_memory(adapter, skb,
573 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800574 dev_kfree_skb_any(skb);
575 }
576 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800577 }
578 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800579 }
580
581 return;
582}
583
584/* This function cleans up RX buffer rings. If any of the buffer list has valid
585 * SKB address, associated SKB is freed.
586 */
587static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
588{
589 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800590 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800591 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800592 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800593 struct sk_buff *skb;
594 int i;
595
596 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800597 if (reg->pfu_enabled) {
598 desc2 = card->rxbd_ring[i];
599 if (card->rx_buf_list[i]) {
600 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800601 mwifiex_unmap_pci_memory(adapter, skb,
602 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800603 dev_kfree_skb_any(skb);
604 }
605 memset(desc2, 0, sizeof(*desc2));
606 } else {
607 desc = card->rxbd_ring[i];
608 if (card->rx_buf_list[i]) {
609 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800610 mwifiex_unmap_pci_memory(adapter, skb,
611 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800612 dev_kfree_skb_any(skb);
613 }
614 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800615 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800616 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800617 }
618
619 return;
620}
621
622/* This function cleans up event buffer rings. If any of the buffer list has
623 * valid SKB address, associated SKB is freed.
624 */
625static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
626{
627 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800628 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800629 struct sk_buff *skb;
630 int i;
631
632 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
633 desc = card->evtbd_ring[i];
634 if (card->evt_buf_list[i]) {
635 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800636 mwifiex_unmap_pci_memory(adapter, skb,
637 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800638 dev_kfree_skb_any(skb);
639 }
640 card->evt_buf_list[i] = NULL;
641 memset(desc, 0, sizeof(*desc));
642 }
643
644 return;
645}
646
647/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700648 */
649static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
650{
651 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800652 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700653
654 /*
655 * driver maintaines the write pointer and firmware maintaines the read
656 * pointer. The write pointer starts at 0 (zero) while the read pointer
657 * starts at zero with rollover bit set
658 */
659 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800660
661 if (reg->pfu_enabled)
662 card->txbd_rdptr = 0;
663 else
664 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700665
666 /* allocate shared memory for the BD ring and divide the same in to
667 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800668 if (reg->pfu_enabled)
669 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
670 MWIFIEX_MAX_TXRX_BD;
671 else
672 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
673 MWIFIEX_MAX_TXRX_BD;
674
Amitkumar Karward930fae2011-10-11 17:41:21 -0700675 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700676 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800677 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
678 card->txbd_ring_size,
679 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700680 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800681 dev_err(adapter->dev,
682 "allocate consistent memory (%d bytes) failed!\n",
683 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800684 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700685 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700686 dev_dbg(adapter->dev,
687 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800688 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700689 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700690
Avinash Patil07324842013-02-08 18:18:07 -0800691 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700692}
693
694static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
695{
696 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800697 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700698
Avinash Patil07324842013-02-08 18:18:07 -0800699 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700700
Avinash Patilfc331462013-01-03 21:21:30 -0800701 if (card->txbd_ring_vbase)
702 pci_free_consistent(card->dev, card->txbd_ring_size,
703 card->txbd_ring_vbase,
704 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700705 card->txbd_ring_size = 0;
706 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800707 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700708 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800709 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700710
711 return 0;
712}
713
714/*
715 * This function creates buffer descriptor ring for RX
716 */
717static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
718{
719 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800720 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700721
722 /*
723 * driver maintaines the read pointer and firmware maintaines the write
724 * pointer. The write pointer starts at 0 (zero) while the read pointer
725 * starts at zero with rollover bit set
726 */
727 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800728 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700729
Avinash Patilca8f2112013-02-08 18:18:09 -0800730 if (reg->pfu_enabled)
731 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
732 MWIFIEX_MAX_TXRX_BD;
733 else
734 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
735 MWIFIEX_MAX_TXRX_BD;
736
Amitkumar Karward930fae2011-10-11 17:41:21 -0700737 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700738 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800739 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
740 card->rxbd_ring_size,
741 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700742 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800743 dev_err(adapter->dev,
744 "allocate consistent memory (%d bytes) failed!\n",
745 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800746 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700747 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700748
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700749 dev_dbg(adapter->dev,
750 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
751 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
752 (u32)((u64)card->rxbd_ring_pbase >> 32),
753 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700754
Avinash Patil07324842013-02-08 18:18:07 -0800755 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700756}
757
758/*
759 * This function deletes Buffer descriptor ring for RX
760 */
761static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
762{
763 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800764 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700765
Avinash Patil07324842013-02-08 18:18:07 -0800766 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700767
Avinash Patilfc331462013-01-03 21:21:30 -0800768 if (card->rxbd_ring_vbase)
769 pci_free_consistent(card->dev, card->rxbd_ring_size,
770 card->rxbd_ring_vbase,
771 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700772 card->rxbd_ring_size = 0;
773 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800774 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700775 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800776 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700777
778 return 0;
779}
780
781/*
782 * This function creates buffer descriptor ring for Events
783 */
784static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
785{
786 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800787 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700788
789 /*
790 * driver maintaines the read pointer and firmware maintaines the write
791 * pointer. The write pointer starts at 0 (zero) while the read pointer
792 * starts at zero with rollover bit set
793 */
794 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800795 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700796
Avinash Patile05dc3e2013-02-08 18:18:08 -0800797 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800798 MWIFIEX_MAX_EVT_BD;
799
Amitkumar Karward930fae2011-10-11 17:41:21 -0700800 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700801 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800802 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
803 card->evtbd_ring_size,
804 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700805 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700806 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800807 "allocate consistent memory (%d bytes) failed!\n",
808 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800809 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700810 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700811
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700812 dev_dbg(adapter->dev,
813 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
814 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
815 (u32)((u64)card->evtbd_ring_pbase >> 32),
816 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700817
Avinash Patil07324842013-02-08 18:18:07 -0800818 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700819}
820
821/*
822 * This function deletes Buffer descriptor ring for Events
823 */
824static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
825{
826 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800827 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700828
Avinash Patil07324842013-02-08 18:18:07 -0800829 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700830
Avinash Patilfc331462013-01-03 21:21:30 -0800831 if (card->evtbd_ring_vbase)
832 pci_free_consistent(card->dev, card->evtbd_ring_size,
833 card->evtbd_ring_vbase,
834 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700835 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800836 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700837 card->evtbd_ring_size = 0;
838 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800839 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700840
841 return 0;
842}
843
844/*
845 * This function allocates a buffer for CMDRSP
846 */
847static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
848{
849 struct pcie_service_card *card = adapter->card;
850 struct sk_buff *skb;
851
852 /* Allocate memory for receiving command response data */
853 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
854 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700855 dev_err(adapter->dev,
856 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700857 return -ENOMEM;
858 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700859 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800860 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
861 PCI_DMA_FROMDEVICE))
862 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700863
Avinash Patilfc331462013-01-03 21:21:30 -0800864 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700865
866 return 0;
867}
868
869/*
870 * This function deletes a buffer for CMDRSP
871 */
872static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
873{
874 struct pcie_service_card *card;
875
876 if (!adapter)
877 return 0;
878
879 card = adapter->card;
880
Avinash Patilfc331462013-01-03 21:21:30 -0800881 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800882 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
883 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700884 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800885 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700886
Avinash Patilfc331462013-01-03 21:21:30 -0800887 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800888 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
889 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800890 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700891 return 0;
892}
893
894/*
895 * This function allocates a buffer for sleep cookie
896 */
897static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
898{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700899 struct pcie_service_card *card = adapter->card;
900
Avinash Patilfc331462013-01-03 21:21:30 -0800901 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
902 &card->sleep_cookie_pbase);
903 if (!card->sleep_cookie_vbase) {
904 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700905 return -ENOMEM;
906 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700907 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800908 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700909
910 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800911 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700912
913 return 0;
914}
915
916/*
917 * This function deletes buffer for sleep cookie
918 */
919static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
920{
921 struct pcie_service_card *card;
922
923 if (!adapter)
924 return 0;
925
926 card = adapter->card;
927
Avinash Patilfc331462013-01-03 21:21:30 -0800928 if (card && card->sleep_cookie_vbase) {
929 pci_free_consistent(card->dev, sizeof(u32),
930 card->sleep_cookie_vbase,
931 card->sleep_cookie_pbase);
932 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700933 }
934
935 return 0;
936}
937
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800938/* This function flushes the TX buffer descriptor ring
939 * This function defined as handler is also called while cleaning TXRX
940 * during disconnect/ bss stop.
941 */
942static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
943{
944 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800945
Avinash Patil48f4d912013-02-20 21:12:58 -0800946 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800947 card->txbd_flush = 1;
948 /* write pointer already set at last send
949 * send dnld-rdy intr again, wait for completion.
950 */
951 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
952 CPU_INTR_DNLD_RDY)) {
953 dev_err(adapter->dev,
954 "failed to assert dnld-rdy interrupt.\n");
955 return -1;
956 }
957 }
958 return 0;
959}
960
Amitkumar Karward930fae2011-10-11 17:41:21 -0700961/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800962 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700963 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800964static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700965{
Avinash Patile7f767a2013-01-03 21:21:32 -0800966 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800967 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800968 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800969 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700970 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800971 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700972
973 if (!mwifiex_pcie_ok_to_access_hw(adapter))
974 mwifiex_pm_wakeup_card(adapter);
975
976 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800977 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700978 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800979 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700980 return -1;
981 }
982
Avinash Patile7f767a2013-01-03 21:21:32 -0800983 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
984 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700985
Avinash Patilca8f2112013-02-08 18:18:09 -0800986 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800987 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800988 while (((card->txbd_rdptr & reg->tx_mask) !=
989 (rdptr & reg->tx_mask)) ||
990 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
991 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800992 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
993 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800994
995 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -0800996
Avinash Patile7f767a2013-01-03 21:21:32 -0800997 if (skb) {
998 dev_dbg(adapter->dev,
999 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
1000 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -08001001 mwifiex_unmap_pci_memory(adapter, skb,
1002 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001003
1004 unmap_count++;
1005
1006 if (card->txbd_flush)
1007 mwifiex_write_data_complete(adapter, skb, 0,
1008 -1);
1009 else
1010 mwifiex_write_data_complete(adapter, skb, 0, 0);
1011 }
1012
1013 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001014
1015 if (reg->pfu_enabled) {
1016 desc2 = (void *)card->txbd_ring[wrdoneidx];
1017 memset(desc2, 0, sizeof(*desc2));
1018 } else {
1019 desc = card->txbd_ring[wrdoneidx];
1020 memset(desc, 0, sizeof(*desc));
1021 }
1022 switch (card->dev->device) {
1023 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1024 card->txbd_rdptr++;
1025 break;
1026 case PCIE_DEVICE_ID_MARVELL_88W8897:
1027 card->txbd_rdptr += reg->ring_tx_start_ptr;
1028 break;
1029 }
1030
Avinash Patile7f767a2013-01-03 21:21:32 -08001031
Avinash Patildd04e6a2013-02-08 18:18:06 -08001032 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001033 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001034 reg->tx_rollover_ind) ^
1035 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001036 }
1037
1038 if (unmap_count)
1039 adapter->data_sent = false;
1040
1041 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001042 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001043 card->txbd_flush = 0;
1044 else
1045 mwifiex_clean_pcie_ring_buf(adapter);
1046 }
1047
1048 return 0;
1049}
1050
1051/* This function sends data buffer to device. First 4 bytes of payload
1052 * are filled with payload length and payload type. Then this payload
1053 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1054 * Download ready interrupt to FW is deffered if Tx ring is not full and
1055 * additional payload can be accomodated.
1056 */
1057static int
1058mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1059 struct mwifiex_tx_param *tx_param)
1060{
1061 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001062 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001063 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001064 int ret;
1065 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001066 struct mwifiex_pcie_buf_desc *desc = NULL;
1067 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001068 __le16 *tmp;
1069
1070 if (!(skb->data && skb->len)) {
1071 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1072 __func__, skb->data, skb->len);
1073 return -1;
1074 }
1075
1076 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1077 mwifiex_pm_wakeup_card(adapter);
1078
Avinash Patilca8f2112013-02-08 18:18:09 -08001079 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001080 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1081 card->txbd_rdptr, card->txbd_wrptr);
1082 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001083 u8 *payload;
1084
1085 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001086 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001087 tmp = (__le16 *)&payload[0];
1088 *tmp = cpu_to_le16((u16)skb->len);
1089 tmp = (__le16 *)&payload[2];
1090 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001091
Aaron Durbindbccc922014-02-07 16:25:50 -08001092 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001093 PCI_DMA_TODEVICE))
1094 return -1;
1095
Avinash Patilca8f2112013-02-08 18:18:09 -08001096 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001097 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001098 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001099
Avinash Patilca8f2112013-02-08 18:18:09 -08001100 if (reg->pfu_enabled) {
1101 desc2 = (void *)card->txbd_ring[wrindx];
1102 desc2->paddr = buf_pa;
1103 desc2->len = (u16)skb->len;
1104 desc2->frag_len = (u16)skb->len;
1105 desc2->offset = 0;
1106 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1107 MWIFIEX_BD_FLAG_LAST_DESC;
1108 } else {
1109 desc = card->txbd_ring[wrindx];
1110 desc->paddr = buf_pa;
1111 desc->len = (u16)skb->len;
1112 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1113 MWIFIEX_BD_FLAG_LAST_DESC;
1114 }
1115
1116 switch (card->dev->device) {
1117 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1118 card->txbd_wrptr++;
1119 break;
1120 case PCIE_DEVICE_ID_MARVELL_88W8897:
1121 card->txbd_wrptr += reg->ring_tx_start_ptr;
1122 break;
1123 }
1124
1125 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001126 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001127 reg->tx_rollover_ind) ^
1128 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001129
Avinash Patilca8f2112013-02-08 18:18:09 -08001130 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001131 /* Write the TX ring write pointer in to reg->tx_wrptr */
1132 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001133 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001134 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001135 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001136 ret = -1;
1137 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001138 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001139 if ((mwifiex_pcie_txbd_not_full(card)) &&
1140 tx_param->next_pkt_len) {
1141 /* have more packets and TxBD still can hold more */
1142 dev_dbg(adapter->dev,
1143 "SEND DATA: delay dnld-rdy interrupt.\n");
1144 adapter->data_sent = false;
1145 } else {
1146 /* Send the TX ready interrupt */
1147 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1148 CPU_INTR_DNLD_RDY)) {
1149 dev_err(adapter->dev,
1150 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1151 ret = -1;
1152 goto done_unmap;
1153 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001154 }
1155 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001156 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001157 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001158 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001159 dev_dbg(adapter->dev,
1160 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001161 adapter->data_sent = true;
1162 /* Send the TX ready interrupt */
1163 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1164 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001165 dev_err(adapter->dev,
1166 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001167 return -EBUSY;
1168 }
1169
Avinash Patile7f767a2013-01-03 21:21:32 -08001170 return -EINPROGRESS;
1171done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001172 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001173 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001174 if (reg->pfu_enabled)
1175 memset(desc2, 0, sizeof(*desc2));
1176 else
1177 memset(desc, 0, sizeof(*desc));
1178
Avinash Patile7f767a2013-01-03 21:21:32 -08001179 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001180}
1181
1182/*
1183 * This function handles received buffer ring and
1184 * dispatches packets to upper
1185 */
1186static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1187{
1188 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001189 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001190 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001191 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001192 int ret = 0;
1193 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001194 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001195 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001196
Avinash Patile7f767a2013-01-03 21:21:32 -08001197 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1198 mwifiex_pm_wakeup_card(adapter);
1199
Amitkumar Karward930fae2011-10-11 17:41:21 -07001200 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001201 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001202 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001203 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001204 ret = -1;
1205 goto done;
1206 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001207 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001208
Avinash Patildd04e6a2013-02-08 18:18:06 -08001209 while (((wrptr & reg->rx_mask) !=
1210 (card->rxbd_rdptr & reg->rx_mask)) ||
1211 ((wrptr & reg->rx_rollover_ind) ==
1212 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001213 struct sk_buff *skb_data;
1214 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001215 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001216
Avinash Patildd04e6a2013-02-08 18:18:06 -08001217 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001218 skb_data = card->rx_buf_list[rd_index];
1219
Aaron Durbindbccc922014-02-07 16:25:50 -08001220 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001221 card->rx_buf_list[rd_index] = NULL;
1222
Amitkumar Karward930fae2011-10-11 17:41:21 -07001223 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001224 * first 2 bytes for len, next 2 bytes is for type
1225 */
1226 pkt_len = *((__le16 *)skb_data->data);
1227 rx_len = le16_to_cpu(pkt_len);
1228 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001229 dev_dbg(adapter->dev,
1230 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1231 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001232 skb_pull(skb_data, INTF_HEADER_LEN);
1233 mwifiex_handle_rx_packet(adapter, skb_data);
1234
1235 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001236 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001237 dev_err(adapter->dev,
1238 "Unable to allocate skb.\n");
1239 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001240 }
1241
Avinash Patile7f767a2013-01-03 21:21:32 -08001242 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1243 MWIFIEX_RX_DATA_BUF_SIZE,
1244 PCI_DMA_FROMDEVICE))
1245 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001246
Aaron Durbindbccc922014-02-07 16:25:50 -08001247 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001248
1249 dev_dbg(adapter->dev,
1250 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1251 skb_tmp, rd_index);
1252 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001253
1254 if (reg->pfu_enabled) {
1255 desc2 = (void *)card->rxbd_ring[rd_index];
1256 desc2->paddr = buf_pa;
1257 desc2->len = skb_tmp->len;
1258 desc2->frag_len = skb_tmp->len;
1259 desc2->offset = 0;
1260 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1261 } else {
1262 desc = card->rxbd_ring[rd_index];
1263 desc->paddr = buf_pa;
1264 desc->len = skb_tmp->len;
1265 desc->flags = 0;
1266 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001267
Avinash Patildd04e6a2013-02-08 18:18:06 -08001268 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001269 MWIFIEX_MAX_TXRX_BD) {
1270 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001271 reg->rx_rollover_ind) ^
1272 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001273 }
1274 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001275 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001276
Avinash Patilca8f2112013-02-08 18:18:09 -08001277 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001278 /* Write the RX ring read pointer in to reg->rx_rdptr */
1279 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001280 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001281 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001282 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001283 ret = -1;
1284 goto done;
1285 }
1286
1287 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001288 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001289 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001290 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001291 ret = -1;
1292 goto done;
1293 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001294 dev_dbg(adapter->dev,
1295 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001296 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001297 }
1298
1299done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001300 return ret;
1301}
1302
1303/*
1304 * This function downloads the boot command to device
1305 */
1306static int
1307mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1308{
Avinash Patilfc331462013-01-03 21:21:30 -08001309 dma_addr_t buf_pa;
1310 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001311 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001312
Avinash Patilfc331462013-01-03 21:21:30 -08001313 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001314 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001315 "Invalid parameter in %s <%p. len %d>\n",
1316 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001317 return -1;
1318 }
1319
Avinash Patilfc331462013-01-03 21:21:30 -08001320 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1321 return -1;
1322
Aaron Durbindbccc922014-02-07 16:25:50 -08001323 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001324
Avinash Patildd04e6a2013-02-08 18:18:06 -08001325 /* Write the lower 32bits of the physical address to low command
1326 * address scratch register
1327 */
1328 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001329 dev_err(adapter->dev,
1330 "%s: failed to write download command to boot code.\n",
1331 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001332 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001333 return -1;
1334 }
1335
Avinash Patildd04e6a2013-02-08 18:18:06 -08001336 /* Write the upper 32bits of the physical address to high command
1337 * address scratch register
1338 */
1339 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001340 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001341 dev_err(adapter->dev,
1342 "%s: failed to write download command to boot code.\n",
1343 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001344 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001345 return -1;
1346 }
1347
Avinash Patildd04e6a2013-02-08 18:18:06 -08001348 /* Write the command length to cmd_size scratch register */
1349 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001350 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001351 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001352 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001353 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001354 return -1;
1355 }
1356
1357 /* Ring the door bell */
1358 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1359 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001360 dev_err(adapter->dev,
1361 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001362 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001363 return -1;
1364 }
1365
1366 return 0;
1367}
1368
Avinash Patilc6d1d872013-01-03 21:21:29 -08001369/* This function init rx port in firmware which in turn enables to receive data
1370 * from device before transmitting any packet.
1371 */
1372static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1373{
1374 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001375 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001376 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001377
Avinash Patildd04e6a2013-02-08 18:18:06 -08001378 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001379 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1380 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001381 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001382 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001383 return -1;
1384 }
1385 return 0;
1386}
1387
1388/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001389 */
1390static int
1391mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1392{
1393 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001394 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001395 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001396 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1397 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001398
1399 if (!(skb->data && skb->len)) {
1400 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001401 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001402 return -1;
1403 }
1404
1405 /* Make sure a command response buffer is available */
1406 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001407 dev_err(adapter->dev,
1408 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001409 return -EBUSY;
1410 }
1411
Avinash Patilfc331462013-01-03 21:21:30 -08001412 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1413 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001414
1415 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001416
1417 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1418 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1419
1420 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1421 return -1;
1422
1423 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001424
1425 /* To send a command, the driver will:
1426 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001427 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001428 2. Ring the door bell (i.e. set the door bell interrupt)
1429
1430 In response to door bell interrupt, the firmware will perform
1431 the DMA of the command packet (first header to obtain the total
1432 length and then rest of the command).
1433 */
1434
1435 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001436 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001437 /* Write the lower 32bits of the cmdrsp buffer physical
1438 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001439 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001440 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001441 dev_err(adapter->dev,
1442 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001443 ret = -1;
1444 goto done;
1445 }
1446 /* Write the upper 32bits of the cmdrsp buffer physical
1447 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001448 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001449 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001450 dev_err(adapter->dev,
1451 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001452 ret = -1;
1453 goto done;
1454 }
1455 }
1456
Aaron Durbindbccc922014-02-07 16:25:50 -08001457 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001458 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1459 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1460 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001461 dev_err(adapter->dev,
1462 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001463 ret = -1;
1464 goto done;
1465 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001466 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1467 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001468 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001469 dev_err(adapter->dev,
1470 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001471 ret = -1;
1472 goto done;
1473 }
1474
Avinash Patildd04e6a2013-02-08 18:18:06 -08001475 /* Write the command length to reg->cmd_size */
1476 if (mwifiex_write_reg(adapter, reg->cmd_size,
1477 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001478 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001479 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001480 ret = -1;
1481 goto done;
1482 }
1483
1484 /* Ring the door bell */
1485 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1486 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001487 dev_err(adapter->dev,
1488 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001489 ret = -1;
1490 goto done;
1491 }
1492
1493done:
1494 if (ret)
1495 adapter->cmd_sent = false;
1496
1497 return 0;
1498}
1499
1500/*
1501 * This function handles command complete interrupt
1502 */
1503static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1504{
1505 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001506 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001507 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001508 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001509 u16 rx_len;
1510 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001511
1512 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1513
Aaron Durbindbccc922014-02-07 16:25:50 -08001514 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001515
Aaron Durbin189b3292014-02-07 16:25:51 -08001516 /* Unmap the command as a response has been received. */
1517 if (card->cmd_buf) {
1518 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1519 PCI_DMA_TODEVICE);
1520 card->cmd_buf = NULL;
1521 }
1522
Avinash Patilfc331462013-01-03 21:21:30 -08001523 pkt_len = *((__le16 *)skb->data);
1524 rx_len = le16_to_cpu(pkt_len);
1525 skb_trim(skb, rx_len);
1526 skb_pull(skb, INTF_HEADER_LEN);
1527
Amitkumar Karward930fae2011-10-11 17:41:21 -07001528 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001529 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001530 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1531 skb->len);
Avinash Patil52301a82013-02-12 14:38:32 -08001532 while (reg->sleep_cookie && (count++ < 10) &&
1533 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001534 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001535 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001536 dev_err(adapter->dev,
1537 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001538 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001539 memcpy(adapter->upld_buf, skb->data,
1540 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001541 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001542 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1543 PCI_DMA_FROMDEVICE))
1544 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001545 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001546 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001547 adapter->cmd_resp_received = true;
1548 /* Take the pointer and set it to CMD node and will
1549 return in the response complete callback */
1550 card->cmdrsp_buf = NULL;
1551
1552 /* Clear the cmd-rsp buffer address in scratch registers. This
1553 will prevent firmware from writing to the same response
1554 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001555 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001556 dev_err(adapter->dev,
1557 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001558 return -1;
1559 }
1560 /* Write the upper 32bits of the cmdrsp buffer physical
1561 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001562 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001563 dev_err(adapter->dev,
1564 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001565 return -1;
1566 }
1567 }
1568
1569 return 0;
1570}
1571
1572/*
1573 * Command Response processing complete handler
1574 */
1575static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1576 struct sk_buff *skb)
1577{
1578 struct pcie_service_card *card = adapter->card;
1579
1580 if (skb) {
1581 card->cmdrsp_buf = skb;
1582 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001583 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1584 PCI_DMA_FROMDEVICE))
1585 return -1;
1586 }
1587
Amitkumar Karward930fae2011-10-11 17:41:21 -07001588 return 0;
1589}
1590
1591/*
1592 * This function handles firmware event ready interrupt
1593 */
1594static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1595{
1596 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001597 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001598 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1599 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001600 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001601
1602 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1603 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001604
1605 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001606 dev_dbg(adapter->dev, "info: Event being processed, "
1607 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001608 return 0;
1609 }
1610
1611 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1612 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1613 return -1;
1614 }
1615
1616 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001617 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001618 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001619 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001620 return -1;
1621 }
1622
1623 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001624 card->evtbd_rdptr, wrptr);
1625 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1626 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001627 ((wrptr & reg->evt_rollover_ind) ==
1628 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001629 struct sk_buff *skb_cmd;
1630 __le16 data_len = 0;
1631 u16 evt_len;
1632
1633 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1634 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001635 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001636
Amitkumar Karward930fae2011-10-11 17:41:21 -07001637 /* Take the pointer and set it to event pointer in adapter
1638 and will return back after event handling callback */
1639 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001640 desc = card->evtbd_ring[rdptr];
1641 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001642
1643 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1644 adapter->event_cause = event;
1645 /* The first 4bytes will be the event transfer header
1646 len is 2 bytes followed by type which is 2 bytes */
1647 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1648 evt_len = le16_to_cpu(data_len);
1649
1650 skb_pull(skb_cmd, INTF_HEADER_LEN);
1651 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1652
1653 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1654 memcpy(adapter->event_body, skb_cmd->data +
1655 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1656 MWIFIEX_EVENT_HEADER_LEN);
1657
1658 adapter->event_received = true;
1659 adapter->event_skb = skb_cmd;
1660
1661 /* Do not update the event read pointer here, wait till the
1662 buffer is released. This is just to make things simpler,
1663 we need to find a better method of managing these buffers.
1664 */
1665 }
1666
1667 return 0;
1668}
1669
1670/*
1671 * Event processing complete handler
1672 */
1673static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1674 struct sk_buff *skb)
1675{
1676 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001677 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001678 int ret = 0;
1679 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1680 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001681 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001682
1683 if (!skb)
1684 return 0;
1685
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001686 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001687 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001688 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001689 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001690 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001691
1692 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001693 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001694 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001695 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001696 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001697 }
1698
1699 if (!card->evt_buf_list[rdptr]) {
1700 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001701 if (mwifiex_map_pci_memory(adapter, skb,
1702 MAX_EVENT_SIZE,
1703 PCI_DMA_FROMDEVICE))
1704 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001705 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001706 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001707 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001708 desc->len = (u16)skb->len;
1709 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001710 skb = NULL;
1711 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001712 dev_dbg(adapter->dev,
1713 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1714 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001715 }
1716
1717 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1718 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001719 reg->evt_rollover_ind) ^
1720 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001721 }
1722
1723 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001724 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001725
Avinash Patildd04e6a2013-02-08 18:18:06 -08001726 /* Write the event ring read pointer in to reg->evt_rdptr */
1727 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1728 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001729 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001730 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001731 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001732 }
1733
Amitkumar Karward930fae2011-10-11 17:41:21 -07001734 dev_dbg(adapter->dev, "info: Check Events Again\n");
1735 ret = mwifiex_pcie_process_event_ready(adapter);
1736
1737 return ret;
1738}
1739
1740/*
1741 * This function downloads the firmware to the card.
1742 *
1743 * Firmware is downloaded to the card in blocks. Every block download
1744 * is tested for CRC errors, and retried a number of times before
1745 * returning failure.
1746 */
1747static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1748 struct mwifiex_fw_image *fw)
1749{
1750 int ret;
1751 u8 *firmware = fw->fw_buf;
1752 u32 firmware_len = fw->fw_len;
1753 u32 offset = 0;
1754 struct sk_buff *skb;
1755 u32 txlen, tx_blocks = 0, tries, len;
1756 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001757 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001758 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001759
1760 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001761 dev_err(adapter->dev,
1762 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001763 return -1;
1764 }
1765
1766 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001767 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001768
1769 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001770 dev_err(adapter->dev,
1771 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001772 return -1;
1773 }
1774
1775 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1776 if (!skb) {
1777 ret = -ENOMEM;
1778 goto done;
1779 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001780
1781 /* Perform firmware data transfer */
1782 do {
1783 u32 ireg_intr = 0;
1784
1785 /* More data? */
1786 if (offset >= firmware_len)
1787 break;
1788
1789 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001790 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001791 &len);
1792 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001793 dev_warn(adapter->dev,
1794 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001795 goto done;
1796 }
1797 if (len)
1798 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001799 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001800 }
1801
1802 if (!len) {
1803 break;
1804 } else if (len > MWIFIEX_UPLD_SIZE) {
1805 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001806 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001807 ret = -1;
1808 goto done;
1809 }
1810
1811 txlen = len;
1812
1813 if (len & BIT(0)) {
1814 block_retry_cnt++;
1815 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1816 pr_err("FW download failure @ %d, over max "
1817 "retry count\n", offset);
1818 ret = -1;
1819 goto done;
1820 }
1821 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001822 "helper: len = 0x%04X, txlen = %d\n",
1823 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001824 len &= ~BIT(0);
1825 /* Setting this to 0 to resend from same offset */
1826 txlen = 0;
1827 } else {
1828 block_retry_cnt = 0;
1829 /* Set blocksize to transfer - checking for
1830 last block */
1831 if (firmware_len - offset < txlen)
1832 txlen = firmware_len - offset;
1833
1834 dev_dbg(adapter->dev, ".");
1835
Avinash Patildd04e6a2013-02-08 18:18:06 -08001836 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1837 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001838
1839 /* Copy payload to buffer */
1840 memmove(skb->data, &firmware[offset], txlen);
1841 }
1842
1843 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001844 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001845
1846 /* Send the boot command to device */
1847 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001848 dev_err(adapter->dev,
1849 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001850 ret = -1;
1851 goto done;
1852 }
Avinash Patilfc331462013-01-03 21:21:30 -08001853
Amitkumar Karward930fae2011-10-11 17:41:21 -07001854 /* Wait for the command done interrupt */
1855 do {
1856 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1857 &ireg_intr)) {
1858 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001859 "interrupt status during fw dnld.\n",
1860 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001861 mwifiex_unmap_pci_memory(adapter, skb,
1862 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001863 ret = -1;
1864 goto done;
1865 }
1866 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1867 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001868
Aaron Durbindbccc922014-02-07 16:25:50 -08001869 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001870
Amitkumar Karward930fae2011-10-11 17:41:21 -07001871 offset += txlen;
1872 } while (true);
1873
1874 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001875 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001876
1877 ret = 0;
1878
1879done:
1880 dev_kfree_skb_any(skb);
1881 return ret;
1882}
1883
1884/*
1885 * This function checks the firmware status in card.
1886 *
1887 * The winner interface is also determined by this function.
1888 */
1889static int
1890mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1891{
1892 int ret = 0;
1893 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001894 struct pcie_service_card *card = adapter->card;
1895 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001896 u32 tries;
1897
1898 /* Mask spurios interrupts */
1899 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001900 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001901 dev_warn(adapter->dev, "Write register failed\n");
1902 return -1;
1903 }
1904
1905 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001906 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1907 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001908 dev_err(adapter->dev,
1909 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001910 return -1;
1911 }
1912
1913 /* Wait for firmware initialization event */
1914 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001915 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001916 &firmware_stat))
1917 ret = -1;
1918 else
1919 ret = 0;
1920 if (ret)
1921 continue;
1922 if (firmware_stat == FIRMWARE_READY_PCIE) {
1923 ret = 0;
1924 break;
1925 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07001926 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001927 ret = -1;
1928 }
1929 }
1930
1931 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001932 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001933 &winner_status))
1934 ret = -1;
1935 else if (!winner_status) {
1936 dev_err(adapter->dev, "PCI-E is the winner\n");
1937 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001938 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001939 dev_err(adapter->dev,
1940 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1941 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001942 }
1943 }
1944
1945 return ret;
1946}
1947
1948/*
1949 * This function reads the interrupt status from card.
1950 */
1951static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1952{
1953 u32 pcie_ireg;
1954 unsigned long flags;
1955
1956 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1957 return;
1958
1959 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1960 dev_warn(adapter->dev, "Read register failed\n");
1961 return;
1962 }
1963
1964 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1965
1966 mwifiex_pcie_disable_host_int(adapter);
1967
1968 /* Clear the pending interrupts */
1969 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1970 ~pcie_ireg)) {
1971 dev_warn(adapter->dev, "Write register failed\n");
1972 return;
1973 }
1974 spin_lock_irqsave(&adapter->int_lock, flags);
1975 adapter->int_status |= pcie_ireg;
1976 spin_unlock_irqrestore(&adapter->int_lock, flags);
1977
1978 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1979 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1980 (adapter->ps_state == PS_STATE_SLEEP)) {
1981 mwifiex_pcie_enable_host_int(adapter);
1982 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001983 PCIE_CPU_INT_EVENT,
1984 CPU_INTR_SLEEP_CFM_DONE)
1985 ) {
1986 dev_warn(adapter->dev,
1987 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001988 return;
1989
1990 }
1991 }
1992 } else if (!adapter->pps_uapsd_mode &&
Avinash Patilc24d9922013-03-22 21:49:06 -07001993 adapter->ps_state == PS_STATE_SLEEP &&
1994 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001995 /* Potentially for PCIe we could get other
1996 * interrupts like shared. Don't change power
1997 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07001998 adapter->ps_state = PS_STATE_AWAKE;
1999 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002000 }
2001 }
2002}
2003
2004/*
2005 * Interrupt handler for PCIe root port
2006 *
2007 * This function reads the interrupt status from firmware and assigns
2008 * the main process in workqueue which will handle the interrupt.
2009 */
2010static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2011{
2012 struct pci_dev *pdev = (struct pci_dev *)context;
2013 struct pcie_service_card *card;
2014 struct mwifiex_adapter *adapter;
2015
2016 if (!pdev) {
2017 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2018 goto exit;
2019 }
2020
Jingoo Hanb2a31202013-09-09 14:26:51 +09002021 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002022 if (!card || !card->adapter) {
2023 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002024 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002025 goto exit;
2026 }
2027 adapter = card->adapter;
2028
2029 if (adapter->surprise_removed)
2030 goto exit;
2031
2032 mwifiex_interrupt_status(adapter);
2033 queue_work(adapter->workqueue, &adapter->main_work);
2034
2035exit:
2036 return IRQ_HANDLED;
2037}
2038
2039/*
2040 * This function checks the current interrupt status.
2041 *
2042 * The following interrupts are checked and handled by this function -
2043 * - Data sent
2044 * - Command sent
2045 * - Command received
2046 * - Packets received
2047 * - Events received
2048 *
2049 * In case of Rx packets received, the packets are uploaded from card to
2050 * host and processed accordingly.
2051 */
2052static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2053{
2054 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002055 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002056 unsigned long flags;
2057
2058 spin_lock_irqsave(&adapter->int_lock, flags);
2059 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002060 pcie_ireg = adapter->int_status;
2061 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002062 spin_unlock_irqrestore(&adapter->int_lock, flags);
2063
Avinash Patil659c4782013-01-03 21:21:28 -08002064 while (pcie_ireg & HOST_INTR_MASK) {
2065 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2066 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002067 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2068 ret = mwifiex_pcie_send_data_complete(adapter);
2069 if (ret)
2070 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002071 }
Avinash Patil659c4782013-01-03 21:21:28 -08002072 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2073 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002074 dev_dbg(adapter->dev, "info: Rx DATA\n");
2075 ret = mwifiex_pcie_process_recv_data(adapter);
2076 if (ret)
2077 return ret;
2078 }
Avinash Patil659c4782013-01-03 21:21:28 -08002079 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2080 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002081 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2082 ret = mwifiex_pcie_process_event_ready(adapter);
2083 if (ret)
2084 return ret;
2085 }
2086
Avinash Patil659c4782013-01-03 21:21:28 -08002087 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2088 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002089 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002090 dev_dbg(adapter->dev,
2091 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002092 adapter->cmd_sent = false;
2093 }
2094 /* Handle command response */
2095 ret = mwifiex_pcie_process_cmd_complete(adapter);
2096 if (ret)
2097 return ret;
2098 }
2099
2100 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2101 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2102 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002103 dev_warn(adapter->dev,
2104 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002105 return -1;
2106 }
2107
2108 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2109 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002110 PCIE_HOST_INT_STATUS,
2111 ~pcie_ireg)) {
2112 dev_warn(adapter->dev,
2113 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002114 return -1;
2115 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002116 }
2117
2118 }
2119 }
2120 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002121 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002122 if (adapter->ps_state != PS_STATE_SLEEP)
2123 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002124
2125 return 0;
2126}
2127
2128/*
2129 * This function downloads data from driver to card.
2130 *
2131 * Both commands and data packets are transferred to the card by this
2132 * function.
2133 *
2134 * This function adds the PCIE specific header to the front of the buffer
2135 * before transferring. The header contains the length of the packet and
2136 * the type. The firmware handles the packets based upon this set type.
2137 */
2138static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2139 struct sk_buff *skb,
2140 struct mwifiex_tx_param *tx_param)
2141{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002142 if (!skb) {
2143 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002144 return -1;
2145 }
2146
2147 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002148 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002149 else if (type == MWIFIEX_TYPE_CMD)
2150 return mwifiex_pcie_send_cmd(adapter, skb);
2151
2152 return 0;
2153}
2154
2155/*
2156 * This function initializes the PCI-E host memory space, WCB rings, etc.
2157 *
2158 * The following initializations steps are followed -
2159 * - Allocate TXBD ring buffers
2160 * - Allocate RXBD ring buffers
2161 * - Allocate event BD ring buffers
2162 * - Allocate command response ring buffer
2163 * - Allocate sleep cookie buffer
2164 */
2165static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2166{
2167 struct pcie_service_card *card = adapter->card;
2168 int ret;
2169 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002170 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002171
2172 pci_set_drvdata(pdev, card);
2173
2174 ret = pci_enable_device(pdev);
2175 if (ret)
2176 goto err_enable_dev;
2177
2178 pci_set_master(pdev);
2179
2180 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2181 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2182 if (ret) {
2183 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2184 goto err_set_dma_mask;
2185 }
2186
2187 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2188 if (ret) {
2189 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2190 goto err_set_dma_mask;
2191 }
2192
2193 ret = pci_request_region(pdev, 0, DRV_NAME);
2194 if (ret) {
2195 dev_err(adapter->dev, "req_reg(0) error\n");
2196 goto err_req_region0;
2197 }
2198 card->pci_mmap = pci_iomap(pdev, 0, 0);
2199 if (!card->pci_mmap) {
2200 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002201 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002202 goto err_iomap0;
2203 }
2204 ret = pci_request_region(pdev, 2, DRV_NAME);
2205 if (ret) {
2206 dev_err(adapter->dev, "req_reg(2) error\n");
2207 goto err_req_region2;
2208 }
2209 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2210 if (!card->pci_mmap1) {
2211 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002212 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002213 goto err_iomap2;
2214 }
2215
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002216 dev_dbg(adapter->dev,
2217 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2218 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002219
2220 card->cmdrsp_buf = NULL;
2221 ret = mwifiex_pcie_create_txbd_ring(adapter);
2222 if (ret)
2223 goto err_cre_txbd;
2224 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2225 if (ret)
2226 goto err_cre_rxbd;
2227 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2228 if (ret)
2229 goto err_cre_evtbd;
2230 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2231 if (ret)
2232 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002233 if (reg->sleep_cookie) {
2234 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2235 if (ret)
2236 goto err_alloc_cookie;
2237 } else {
2238 card->sleep_cookie_vbase = NULL;
2239 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002240 return ret;
2241
2242err_alloc_cookie:
2243 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2244err_alloc_cmdbuf:
2245 mwifiex_pcie_delete_evtbd_ring(adapter);
2246err_cre_evtbd:
2247 mwifiex_pcie_delete_rxbd_ring(adapter);
2248err_cre_rxbd:
2249 mwifiex_pcie_delete_txbd_ring(adapter);
2250err_cre_txbd:
2251 pci_iounmap(pdev, card->pci_mmap1);
2252err_iomap2:
2253 pci_release_region(pdev, 2);
2254err_req_region2:
2255 pci_iounmap(pdev, card->pci_mmap);
2256err_iomap0:
2257 pci_release_region(pdev, 0);
2258err_req_region0:
2259err_set_dma_mask:
2260 pci_disable_device(pdev);
2261err_enable_dev:
2262 pci_set_drvdata(pdev, NULL);
2263 return ret;
2264}
2265
2266/*
2267 * This function cleans up the allocated card buffers.
2268 *
2269 * The following are freed by this function -
2270 * - TXBD ring buffers
2271 * - RXBD ring buffers
2272 * - Event BD ring buffers
2273 * - Command response ring buffer
2274 * - Sleep cookie buffer
2275 */
2276static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2277{
2278 struct pcie_service_card *card = adapter->card;
2279 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002280 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002281
Amitkumar Karward930fae2011-10-11 17:41:21 -07002282 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002283 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002284 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002285 dev_err(adapter->dev,
2286 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002287 }
2288
2289 if (pdev) {
2290 pci_iounmap(pdev, card->pci_mmap);
2291 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002292 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002293 pci_release_region(pdev, 2);
2294 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002295 pci_set_drvdata(pdev, NULL);
2296 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002297 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002298}
2299
2300/*
2301 * This function registers the PCIE device.
2302 *
2303 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2304 */
2305static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2306{
2307 int ret;
2308 struct pcie_service_card *card = adapter->card;
2309 struct pci_dev *pdev = card->dev;
2310
2311 /* save adapter pointer in card */
2312 card->adapter = adapter;
2313
2314 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2315 "MRVL_PCIE", pdev);
2316 if (ret) {
2317 pr_err("request_irq failed: ret=%d\n", ret);
2318 adapter->card = NULL;
2319 return -1;
2320 }
2321
2322 adapter->dev = &pdev->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002323 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002324
2325 return 0;
2326}
2327
2328/*
2329 * This function unregisters the PCIE device.
2330 *
2331 * The PCIE IRQ is released, the function is disabled and driver
2332 * data is set to null.
2333 */
2334static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2335{
2336 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002337 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002338
2339 if (card) {
2340 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2341 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002342
Avinash Patil52301a82013-02-12 14:38:32 -08002343 reg = card->pcie.reg;
2344 if (reg->sleep_cookie)
2345 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2346
Avinash Patilfc331462013-01-03 21:21:30 -08002347 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2348 mwifiex_pcie_delete_evtbd_ring(adapter);
2349 mwifiex_pcie_delete_rxbd_ring(adapter);
2350 mwifiex_pcie_delete_txbd_ring(adapter);
2351 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002352 }
2353}
2354
2355static struct mwifiex_if_ops pcie_ops = {
2356 .init_if = mwifiex_pcie_init,
2357 .cleanup_if = mwifiex_pcie_cleanup,
2358 .check_fw_status = mwifiex_check_fw_status,
2359 .prog_fw = mwifiex_prog_fw_w_helper,
2360 .register_dev = mwifiex_register_dev,
2361 .unregister_dev = mwifiex_unregister_dev,
2362 .enable_int = mwifiex_pcie_enable_host_int,
2363 .process_int_status = mwifiex_process_int_status,
2364 .host_to_card = mwifiex_pcie_host_to_card,
2365 .wakeup = mwifiex_pm_wakeup_card,
2366 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2367
2368 /* PCIE specific */
2369 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2370 .event_complete = mwifiex_pcie_event_complete,
2371 .update_mp_end_port = NULL,
2372 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002373 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002374 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002375};
2376
2377/*
2378 * This function initializes the PCIE driver module.
2379 *
2380 * This initiates the semaphore and registers the device with
2381 * PCIE bus.
2382 */
2383static int mwifiex_pcie_init_module(void)
2384{
2385 int ret;
2386
Avinash Patilca8f2112013-02-08 18:18:09 -08002387 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002388
2389 sema_init(&add_remove_card_sem, 1);
2390
2391 /* Clear the flag in case user removes the card. */
2392 user_rmmod = 0;
2393
2394 ret = pci_register_driver(&mwifiex_pcie);
2395 if (ret)
2396 pr_err("Driver register failed!\n");
2397 else
2398 pr_debug("info: Driver registered successfully!\n");
2399
2400 return ret;
2401}
2402
2403/*
2404 * This function cleans up the PCIE driver.
2405 *
2406 * The following major steps are followed for cleanup -
2407 * - Resume the device if its suspended
2408 * - Disconnect the device if connected
2409 * - Shutdown the firmware
2410 * - Unregister the device from PCIE bus.
2411 */
2412static void mwifiex_pcie_cleanup_module(void)
2413{
2414 if (!down_interruptible(&add_remove_card_sem))
2415 up(&add_remove_card_sem);
2416
2417 /* Set the flag as user is removing this module. */
2418 user_rmmod = 1;
2419
2420 pci_unregister_driver(&mwifiex_pcie);
2421}
2422
2423module_init(mwifiex_pcie_init_module);
2424module_exit(mwifiex_pcie_cleanup_module);
2425
2426MODULE_AUTHOR("Marvell International Ltd.");
2427MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2428MODULE_VERSION(PCIE_VERSION);
2429MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002430MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2431MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);