blob: 52da8ee7599a041d7922180122c1744d19fe743e [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,
42 int 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;
45 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -070046
Avinash Patilfc331462013-01-03 21:21:30 -080047 buf_pa = pci_map_single(card->dev, skb->data, size, flags);
48 if (pci_dma_mapping_error(card->dev, buf_pa)) {
49 dev_err(adapter->dev, "failed to map pci memory!\n");
50 return -1;
51 }
52 memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t));
53 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070054}
55
56/*
57 * This function reads sleep cookie and checks if FW is ready
58 */
59static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
60{
61 u32 *cookie_addr;
62 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080063 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
64
65 if (!reg->sleep_cookie)
66 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070067
Avinash Patilfc331462013-01-03 21:21:30 -080068 if (card->sleep_cookie_vbase) {
69 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070070 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
71 *cookie_addr);
72 if (*cookie_addr == FW_AWAKE_COOKIE)
73 return true;
74 }
75
76 return false;
77}
78
Shuah Khan3266d732013-07-03 10:47:10 -060079#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -070080/*
Bing Zhaofcca8d52013-03-04 16:27:53 -080081 * Kernel needs to suspend all functions separately. Therefore all
82 * registered functions must have drivers with suspend and resume
83 * methods. Failing that the kernel simply removes the whole card.
84 *
85 * If already not suspended, this function allocates and sends a host
86 * sleep activate request to the firmware and turns off the traffic.
87 */
Shuah Khan3266d732013-07-03 10:47:10 -060088static int mwifiex_pcie_suspend(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -080089{
90 struct mwifiex_adapter *adapter;
91 struct pcie_service_card *card;
92 int hs_actived;
Shuah Khan3266d732013-07-03 10:47:10 -060093 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -080094
95 if (pdev) {
96 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
97 if (!card || !card->adapter) {
98 pr_err("Card or adapter structure is not valid\n");
99 return 0;
100 }
101 } else {
102 pr_err("PCIE device is not specified\n");
103 return 0;
104 }
105
106 adapter = card->adapter;
107
108 hs_actived = mwifiex_enable_hs(adapter);
109
110 /* Indicate device suspended */
111 adapter->is_suspended = true;
112
113 return 0;
114}
115
116/*
117 * Kernel needs to suspend all functions separately. Therefore all
118 * registered functions must have drivers with suspend and resume
119 * methods. Failing that the kernel simply removes the whole card.
120 *
121 * If already not resumed, this function turns on the traffic and
122 * sends a host sleep cancel request to the firmware.
123 */
Shuah Khan3266d732013-07-03 10:47:10 -0600124static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800125{
126 struct mwifiex_adapter *adapter;
127 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600128 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800129
130 if (pdev) {
131 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
132 if (!card || !card->adapter) {
133 pr_err("Card or adapter structure is not valid\n");
134 return 0;
135 }
136 } else {
137 pr_err("PCIE device is not specified\n");
138 return 0;
139 }
140
141 adapter = card->adapter;
142
143 if (!adapter->is_suspended) {
144 dev_warn(adapter->dev, "Device already resumed\n");
145 return 0;
146 }
147
148 adapter->is_suspended = false;
149
150 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
151 MWIFIEX_ASYNC_CMD);
152
153 return 0;
154}
Bing Zhao8509e822013-03-04 16:27:54 -0800155#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800156
157/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700158 * This function probes an mwifiex device and registers it. It allocates
159 * the card structure, enables PCIE function number and initiates the
160 * device registration and initialization procedure by adding a logical
161 * interface.
162 */
163static int mwifiex_pcie_probe(struct pci_dev *pdev,
164 const struct pci_device_id *ent)
165{
166 struct pcie_service_card *card;
167
168 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700169 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700170
171 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000172 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700173 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700174
175 card->dev = pdev;
176
Avinash Patildd04e6a2013-02-08 18:18:06 -0800177 if (ent->driver_data) {
178 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
179 card->pcie.firmware = data->firmware;
180 card->pcie.reg = data->reg;
181 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
182 }
183
Amitkumar Karward930fae2011-10-11 17:41:21 -0700184 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
185 MWIFIEX_PCIE)) {
186 pr_err("%s failed\n", __func__);
187 kfree(card);
188 return -1;
189 }
190
191 return 0;
192}
193
194/*
195 * This function removes the interface and frees up the card structure.
196 */
197static void mwifiex_pcie_remove(struct pci_dev *pdev)
198{
199 struct pcie_service_card *card;
200 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700201 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700202 int i;
203
204 card = pci_get_drvdata(pdev);
205 if (!card)
206 return;
207
208 adapter = card->adapter;
209 if (!adapter || !adapter->priv_num)
210 return;
211
Amitkumar Karwar59a4cc22012-04-09 20:06:57 -0700212 /* In case driver is removed when asynchronous FW load is in progress */
213 wait_for_completion(&adapter->fw_load);
214
Amitkumar Karward930fae2011-10-11 17:41:21 -0700215 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600216#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700217 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600218 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700219#endif
220
221 for (i = 0; i < adapter->priv_num; i++)
222 if ((GET_BSS_ROLE(adapter->priv[i]) ==
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700223 MWIFIEX_BSS_ROLE_STA) &&
224 adapter->priv[i]->media_connected)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700225 mwifiex_deauthenticate(adapter->priv[i], NULL);
226
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700227 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700228
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700229 mwifiex_disable_auto_ds(priv);
230
231 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700232 }
233
234 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
235 kfree(card);
236}
237
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700238static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
239{
240 user_rmmod = 1;
241 mwifiex_pcie_remove(pdev);
242
243 return;
244}
245
Amitkumar Karward930fae2011-10-11 17:41:21 -0700246static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
247 {
248 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
249 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800250 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700251 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800252 {
253 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
254 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
255 .driver_data = (unsigned long) &mwifiex_pcie8897,
256 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700257 {},
258};
259
260MODULE_DEVICE_TABLE(pci, mwifiex_ids);
261
Shuah Khan3266d732013-07-03 10:47:10 -0600262#ifdef CONFIG_PM_SLEEP
263/* Power Management Hooks */
264static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
265 mwifiex_pcie_resume);
266#endif
267
Amitkumar Karward930fae2011-10-11 17:41:21 -0700268/* PCI Device Driver */
269static struct pci_driver __refdata mwifiex_pcie = {
270 .name = "mwifiex_pcie",
271 .id_table = mwifiex_ids,
272 .probe = mwifiex_pcie_probe,
273 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600274#ifdef CONFIG_PM_SLEEP
275 .driver = {
276 .pm = &mwifiex_pcie_pm_ops,
277 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700278#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700279 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700280};
281
282/*
283 * This function writes data into PCIE card register.
284 */
285static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
286{
287 struct pcie_service_card *card = adapter->card;
288
289 iowrite32(data, card->pci_mmap1 + reg);
290
291 return 0;
292}
293
294/*
295 * This function reads data from PCIE card register.
296 */
297static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
298{
299 struct pcie_service_card *card = adapter->card;
300
301 *data = ioread32(card->pci_mmap1 + reg);
302
303 return 0;
304}
305
306/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700307 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700308 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700309static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700310{
311 int i = 0;
312
Avinash Patilc0880a22013-03-22 21:49:07 -0700313 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700314 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700315 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700316 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800317 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700318 break;
319 }
320
Avinash Patilc0880a22013-03-22 21:49:07 -0700321 return;
322}
323
324/* This function wakes up the card by reading fw_status register. */
325static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
326{
327 u32 fw_status;
328 struct pcie_service_card *card = adapter->card;
329 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
330
Amitkumar Karward930fae2011-10-11 17:41:21 -0700331 dev_dbg(adapter->dev, "event: Wakeup device...\n");
332
Avinash Patilc0880a22013-03-22 21:49:07 -0700333 if (reg->sleep_cookie)
334 mwifiex_pcie_dev_wakeup_delay(adapter);
335
336 /* Reading fw_status register will wakeup device */
337 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
338 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700339 return -1;
340 }
341
Avinash Patilc0880a22013-03-22 21:49:07 -0700342 if (reg->sleep_cookie) {
343 mwifiex_pcie_dev_wakeup_delay(adapter);
344 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
345 adapter->ps_state = PS_STATE_AWAKE;
346 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700347
348 return 0;
349}
350
351/*
352 * This function is called after the card has woken up.
353 *
354 * The card configuration register is reset.
355 */
356static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
357{
358 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
359
360 return 0;
361}
362
363/*
364 * This function disables the host interrupt.
365 *
366 * The host interrupt mask is read, the disable bit is reset and
367 * written back to the card host interrupt mask register.
368 */
369static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
370{
371 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
372 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
373 0x00000000)) {
374 dev_warn(adapter->dev, "Disable host interrupt failed\n");
375 return -1;
376 }
377 }
378
379 return 0;
380}
381
382/*
383 * This function enables the host interrupt.
384 *
385 * The host interrupt enable mask is written to the card
386 * host interrupt mask register.
387 */
388static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
389{
390 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
391 /* Simply write the mask to the register */
392 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
393 HOST_INTR_MASK)) {
394 dev_warn(adapter->dev, "Enable host interrupt failed\n");
395 return -1;
396 }
397 }
398
399 return 0;
400}
401
402/*
Avinash Patil07324842013-02-08 18:18:07 -0800403 * This function initializes TX buffer ring descriptors
404 */
405static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
406{
407 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800408 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800409 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800410 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800411 int i;
412
413 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
414 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800415 if (reg->pfu_enabled) {
416 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
417 (sizeof(*desc2) * i);
418 desc2 = card->txbd_ring[i];
419 memset(desc2, 0, sizeof(*desc2));
420 } else {
421 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
422 (sizeof(*desc) * i);
423 desc = card->txbd_ring[i];
424 memset(desc, 0, sizeof(*desc));
425 }
Avinash Patil07324842013-02-08 18:18:07 -0800426 }
427
428 return 0;
429}
430
431/* This function initializes RX buffer ring descriptors. Each SKB is allocated
432 * here and after mapping PCI memory, its physical address is assigned to
433 * PCIE Rx buffer descriptor's physical address.
434 */
435static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
436{
437 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800438 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800439 struct sk_buff *skb;
440 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800441 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800442 dma_addr_t buf_pa;
443 int i;
444
445 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
446 /* Allocate skb here so that firmware can DMA data from it */
447 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
448 if (!skb) {
449 dev_err(adapter->dev,
450 "Unable to allocate skb for RX ring.\n");
451 kfree(card->rxbd_ring_vbase);
452 return -ENOMEM;
453 }
454
455 if (mwifiex_map_pci_memory(adapter, skb,
456 MWIFIEX_RX_DATA_BUF_SIZE,
457 PCI_DMA_FROMDEVICE))
458 return -1;
459
460 MWIFIEX_SKB_PACB(skb, &buf_pa);
461
462 dev_dbg(adapter->dev,
463 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
464 skb, skb->len, skb->data, (u32)buf_pa,
465 (u32)((u64)buf_pa >> 32));
466
467 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800468 if (reg->pfu_enabled) {
469 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
470 (sizeof(*desc2) * i);
471 desc2 = card->rxbd_ring[i];
472 desc2->paddr = buf_pa;
473 desc2->len = (u16)skb->len;
474 desc2->frag_len = (u16)skb->len;
475 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
476 desc2->offset = 0;
477 } else {
478 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
479 (sizeof(*desc) * i));
480 desc = card->rxbd_ring[i];
481 desc->paddr = buf_pa;
482 desc->len = (u16)skb->len;
483 desc->flags = 0;
484 }
Avinash Patil07324842013-02-08 18:18:07 -0800485 }
486
487 return 0;
488}
489
490/* This function initializes event buffer ring descriptors. Each SKB is
491 * allocated here and after mapping PCI memory, its physical address is assigned
492 * to PCIE Rx buffer descriptor's physical address
493 */
494static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
495{
496 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800497 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800498 struct sk_buff *skb;
499 dma_addr_t buf_pa;
500 int i;
501
502 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
503 /* Allocate skb here so that firmware can DMA data from it */
504 skb = dev_alloc_skb(MAX_EVENT_SIZE);
505 if (!skb) {
506 dev_err(adapter->dev,
507 "Unable to allocate skb for EVENT buf.\n");
508 kfree(card->evtbd_ring_vbase);
509 return -ENOMEM;
510 }
511 skb_put(skb, MAX_EVENT_SIZE);
512
513 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
514 PCI_DMA_FROMDEVICE))
515 return -1;
516
517 MWIFIEX_SKB_PACB(skb, &buf_pa);
518
519 dev_dbg(adapter->dev,
520 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
521 skb, skb->len, skb->data, (u32)buf_pa,
522 (u32)((u64)buf_pa >> 32));
523
524 card->evt_buf_list[i] = skb;
525 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
526 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800527 desc = card->evtbd_ring[i];
528 desc->paddr = buf_pa;
529 desc->len = (u16)skb->len;
530 desc->flags = 0;
531 }
532
533 return 0;
534}
535
536/* This function cleans up TX buffer rings. If any of the buffer list has valid
537 * SKB address, associated SKB is freed.
538 */
539static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
540{
541 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800542 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800543 struct sk_buff *skb;
544 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800545 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800546 int i;
547
548 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800549 if (reg->pfu_enabled) {
550 desc2 = card->txbd_ring[i];
551 if (card->tx_buf_list[i]) {
552 skb = card->tx_buf_list[i];
553 pci_unmap_single(card->dev, desc2->paddr,
554 skb->len, PCI_DMA_TODEVICE);
555 dev_kfree_skb_any(skb);
556 }
557 memset(desc2, 0, sizeof(*desc2));
558 } else {
559 desc = card->txbd_ring[i];
560 if (card->tx_buf_list[i]) {
561 skb = card->tx_buf_list[i];
562 pci_unmap_single(card->dev, desc->paddr,
563 skb->len, PCI_DMA_TODEVICE);
564 dev_kfree_skb_any(skb);
565 }
566 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800567 }
568 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800569 }
570
571 return;
572}
573
574/* This function cleans up RX buffer rings. If any of the buffer list has valid
575 * SKB address, associated SKB is freed.
576 */
577static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
578{
579 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800580 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800581 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800582 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800583 struct sk_buff *skb;
584 int i;
585
586 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800587 if (reg->pfu_enabled) {
588 desc2 = card->rxbd_ring[i];
589 if (card->rx_buf_list[i]) {
590 skb = card->rx_buf_list[i];
591 pci_unmap_single(card->dev, desc2->paddr,
Avinash Patild033d3a2013-04-19 17:44:42 -0700592 skb->len, PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800593 dev_kfree_skb_any(skb);
594 }
595 memset(desc2, 0, sizeof(*desc2));
596 } else {
597 desc = card->rxbd_ring[i];
598 if (card->rx_buf_list[i]) {
599 skb = card->rx_buf_list[i];
600 pci_unmap_single(card->dev, desc->paddr,
Avinash Patild033d3a2013-04-19 17:44:42 -0700601 skb->len, PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800602 dev_kfree_skb_any(skb);
603 }
604 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800605 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800606 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800607 }
608
609 return;
610}
611
612/* This function cleans up event buffer rings. If any of the buffer list has
613 * valid SKB address, associated SKB is freed.
614 */
615static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
616{
617 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800618 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800619 struct sk_buff *skb;
620 int i;
621
622 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
623 desc = card->evtbd_ring[i];
624 if (card->evt_buf_list[i]) {
625 skb = card->evt_buf_list[i];
626 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE,
627 PCI_DMA_FROMDEVICE);
628 dev_kfree_skb_any(skb);
629 }
630 card->evt_buf_list[i] = NULL;
631 memset(desc, 0, sizeof(*desc));
632 }
633
634 return;
635}
636
637/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700638 */
639static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
640{
641 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800642 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700643
644 /*
645 * driver maintaines the write pointer and firmware maintaines the read
646 * pointer. The write pointer starts at 0 (zero) while the read pointer
647 * starts at zero with rollover bit set
648 */
649 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800650
651 if (reg->pfu_enabled)
652 card->txbd_rdptr = 0;
653 else
654 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700655
656 /* allocate shared memory for the BD ring and divide the same in to
657 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800658 if (reg->pfu_enabled)
659 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
660 MWIFIEX_MAX_TXRX_BD;
661 else
662 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
663 MWIFIEX_MAX_TXRX_BD;
664
Amitkumar Karward930fae2011-10-11 17:41:21 -0700665 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700666 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800667 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
668 card->txbd_ring_size,
669 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700670 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800671 dev_err(adapter->dev,
672 "allocate consistent memory (%d bytes) failed!\n",
673 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800674 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700675 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700676 dev_dbg(adapter->dev,
677 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800678 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700679 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700680
Avinash Patil07324842013-02-08 18:18:07 -0800681 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700682}
683
684static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
685{
686 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800687 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700688
Avinash Patil07324842013-02-08 18:18:07 -0800689 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700690
Avinash Patilfc331462013-01-03 21:21:30 -0800691 if (card->txbd_ring_vbase)
692 pci_free_consistent(card->dev, card->txbd_ring_size,
693 card->txbd_ring_vbase,
694 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700695 card->txbd_ring_size = 0;
696 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800697 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700698 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800699 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700700
701 return 0;
702}
703
704/*
705 * This function creates buffer descriptor ring for RX
706 */
707static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
708{
709 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800710 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700711
712 /*
713 * driver maintaines the read pointer and firmware maintaines the write
714 * pointer. The write pointer starts at 0 (zero) while the read pointer
715 * starts at zero with rollover bit set
716 */
717 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800718 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700719
Avinash Patilca8f2112013-02-08 18:18:09 -0800720 if (reg->pfu_enabled)
721 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
722 MWIFIEX_MAX_TXRX_BD;
723 else
724 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
725 MWIFIEX_MAX_TXRX_BD;
726
Amitkumar Karward930fae2011-10-11 17:41:21 -0700727 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700728 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800729 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
730 card->rxbd_ring_size,
731 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700732 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800733 dev_err(adapter->dev,
734 "allocate consistent memory (%d bytes) failed!\n",
735 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800736 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700737 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700738
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700739 dev_dbg(adapter->dev,
740 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
741 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
742 (u32)((u64)card->rxbd_ring_pbase >> 32),
743 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700744
Avinash Patil07324842013-02-08 18:18:07 -0800745 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700746}
747
748/*
749 * This function deletes Buffer descriptor ring for RX
750 */
751static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
752{
753 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800754 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700755
Avinash Patil07324842013-02-08 18:18:07 -0800756 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700757
Avinash Patilfc331462013-01-03 21:21:30 -0800758 if (card->rxbd_ring_vbase)
759 pci_free_consistent(card->dev, card->rxbd_ring_size,
760 card->rxbd_ring_vbase,
761 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700762 card->rxbd_ring_size = 0;
763 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800764 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700765 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800766 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700767
768 return 0;
769}
770
771/*
772 * This function creates buffer descriptor ring for Events
773 */
774static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
775{
776 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800777 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700778
779 /*
780 * driver maintaines the read pointer and firmware maintaines the write
781 * pointer. The write pointer starts at 0 (zero) while the read pointer
782 * starts at zero with rollover bit set
783 */
784 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800785 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700786
Avinash Patile05dc3e2013-02-08 18:18:08 -0800787 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800788 MWIFIEX_MAX_EVT_BD;
789
Amitkumar Karward930fae2011-10-11 17:41:21 -0700790 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700791 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800792 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
793 card->evtbd_ring_size,
794 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700795 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700796 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800797 "allocate consistent memory (%d bytes) failed!\n",
798 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800799 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700800 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700801
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700802 dev_dbg(adapter->dev,
803 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
804 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
805 (u32)((u64)card->evtbd_ring_pbase >> 32),
806 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700807
Avinash Patil07324842013-02-08 18:18:07 -0800808 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700809}
810
811/*
812 * This function deletes Buffer descriptor ring for Events
813 */
814static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
815{
816 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800817 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700818
Avinash Patil07324842013-02-08 18:18:07 -0800819 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700820
Avinash Patilfc331462013-01-03 21:21:30 -0800821 if (card->evtbd_ring_vbase)
822 pci_free_consistent(card->dev, card->evtbd_ring_size,
823 card->evtbd_ring_vbase,
824 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700825 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800826 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700827 card->evtbd_ring_size = 0;
828 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800829 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700830
831 return 0;
832}
833
834/*
835 * This function allocates a buffer for CMDRSP
836 */
837static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
838{
839 struct pcie_service_card *card = adapter->card;
840 struct sk_buff *skb;
841
842 /* Allocate memory for receiving command response data */
843 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
844 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700845 dev_err(adapter->dev,
846 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700847 return -ENOMEM;
848 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700849 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800850 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
851 PCI_DMA_FROMDEVICE))
852 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700853
Avinash Patilfc331462013-01-03 21:21:30 -0800854 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700855
856 return 0;
857}
858
859/*
860 * This function deletes a buffer for CMDRSP
861 */
862static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
863{
864 struct pcie_service_card *card;
Avinash Patilfc331462013-01-03 21:21:30 -0800865 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700866
867 if (!adapter)
868 return 0;
869
870 card = adapter->card;
871
Avinash Patilfc331462013-01-03 21:21:30 -0800872 if (card && card->cmdrsp_buf) {
873 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
874 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
875 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700876 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800877 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700878
Avinash Patilfc331462013-01-03 21:21:30 -0800879 if (card && card->cmd_buf) {
880 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
Yogesh Ashok Powar7af1ce02013-04-23 16:49:50 -0700881 pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len,
Avinash Patilfc331462013-01-03 21:21:30 -0800882 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800883 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700884 return 0;
885}
886
887/*
888 * This function allocates a buffer for sleep cookie
889 */
890static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
891{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700892 struct pcie_service_card *card = adapter->card;
893
Avinash Patilfc331462013-01-03 21:21:30 -0800894 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
895 &card->sleep_cookie_pbase);
896 if (!card->sleep_cookie_vbase) {
897 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700898 return -ENOMEM;
899 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700900 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800901 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700902
903 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800904 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700905
906 return 0;
907}
908
909/*
910 * This function deletes buffer for sleep cookie
911 */
912static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
913{
914 struct pcie_service_card *card;
915
916 if (!adapter)
917 return 0;
918
919 card = adapter->card;
920
Avinash Patilfc331462013-01-03 21:21:30 -0800921 if (card && card->sleep_cookie_vbase) {
922 pci_free_consistent(card->dev, sizeof(u32),
923 card->sleep_cookie_vbase,
924 card->sleep_cookie_pbase);
925 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700926 }
927
928 return 0;
929}
930
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800931/* This function flushes the TX buffer descriptor ring
932 * This function defined as handler is also called while cleaning TXRX
933 * during disconnect/ bss stop.
934 */
935static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
936{
937 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800938
Avinash Patil48f4d912013-02-20 21:12:58 -0800939 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800940 card->txbd_flush = 1;
941 /* write pointer already set at last send
942 * send dnld-rdy intr again, wait for completion.
943 */
944 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
945 CPU_INTR_DNLD_RDY)) {
946 dev_err(adapter->dev,
947 "failed to assert dnld-rdy interrupt.\n");
948 return -1;
949 }
950 }
951 return 0;
952}
953
Amitkumar Karward930fae2011-10-11 17:41:21 -0700954/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800955 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700956 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800957static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700958{
Avinash Patile7f767a2013-01-03 21:21:32 -0800959 struct sk_buff *skb;
960 dma_addr_t buf_pa;
Avinash Patilca8f2112013-02-08 18:18:09 -0800961 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800962 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800963 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700964 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800965 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700966
967 if (!mwifiex_pcie_ok_to_access_hw(adapter))
968 mwifiex_pm_wakeup_card(adapter);
969
970 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800971 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700972 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800973 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700974 return -1;
975 }
976
Avinash Patile7f767a2013-01-03 21:21:32 -0800977 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
978 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700979
Avinash Patilca8f2112013-02-08 18:18:09 -0800980 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800981 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800982 while (((card->txbd_rdptr & reg->tx_mask) !=
983 (rdptr & reg->tx_mask)) ||
984 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
985 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800986 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
987 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800988
989 skb = card->tx_buf_list[wrdoneidx];
990 if (skb) {
991 dev_dbg(adapter->dev,
992 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
993 skb, wrdoneidx);
994 MWIFIEX_SKB_PACB(skb, &buf_pa);
995 pci_unmap_single(card->dev, buf_pa, skb->len,
996 PCI_DMA_TODEVICE);
997
998 unmap_count++;
999
1000 if (card->txbd_flush)
1001 mwifiex_write_data_complete(adapter, skb, 0,
1002 -1);
1003 else
1004 mwifiex_write_data_complete(adapter, skb, 0, 0);
1005 }
1006
1007 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001008
1009 if (reg->pfu_enabled) {
1010 desc2 = (void *)card->txbd_ring[wrdoneidx];
1011 memset(desc2, 0, sizeof(*desc2));
1012 } else {
1013 desc = card->txbd_ring[wrdoneidx];
1014 memset(desc, 0, sizeof(*desc));
1015 }
1016 switch (card->dev->device) {
1017 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1018 card->txbd_rdptr++;
1019 break;
1020 case PCIE_DEVICE_ID_MARVELL_88W8897:
1021 card->txbd_rdptr += reg->ring_tx_start_ptr;
1022 break;
1023 }
1024
Avinash Patile7f767a2013-01-03 21:21:32 -08001025
Avinash Patildd04e6a2013-02-08 18:18:06 -08001026 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001027 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001028 reg->tx_rollover_ind) ^
1029 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001030 }
1031
1032 if (unmap_count)
1033 adapter->data_sent = false;
1034
1035 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001036 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001037 card->txbd_flush = 0;
1038 else
1039 mwifiex_clean_pcie_ring_buf(adapter);
1040 }
1041
1042 return 0;
1043}
1044
1045/* This function sends data buffer to device. First 4 bytes of payload
1046 * are filled with payload length and payload type. Then this payload
1047 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1048 * Download ready interrupt to FW is deffered if Tx ring is not full and
1049 * additional payload can be accomodated.
1050 */
1051static int
1052mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1053 struct mwifiex_tx_param *tx_param)
1054{
1055 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001056 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001057 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001058 int ret;
1059 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001060 struct mwifiex_pcie_buf_desc *desc = NULL;
1061 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001062 __le16 *tmp;
1063
1064 if (!(skb->data && skb->len)) {
1065 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1066 __func__, skb->data, skb->len);
1067 return -1;
1068 }
1069
1070 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1071 mwifiex_pm_wakeup_card(adapter);
1072
Avinash Patilca8f2112013-02-08 18:18:09 -08001073 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001074 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1075 card->txbd_rdptr, card->txbd_wrptr);
1076 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001077 u8 *payload;
1078
1079 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001080 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001081 tmp = (__le16 *)&payload[0];
1082 *tmp = cpu_to_le16((u16)skb->len);
1083 tmp = (__le16 *)&payload[2];
1084 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001085
1086 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
1087 PCI_DMA_TODEVICE))
1088 return -1;
1089
Avinash Patilca8f2112013-02-08 18:18:09 -08001090 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001091 MWIFIEX_SKB_PACB(skb, &buf_pa);
1092 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001093
Avinash Patilca8f2112013-02-08 18:18:09 -08001094 if (reg->pfu_enabled) {
1095 desc2 = (void *)card->txbd_ring[wrindx];
1096 desc2->paddr = buf_pa;
1097 desc2->len = (u16)skb->len;
1098 desc2->frag_len = (u16)skb->len;
1099 desc2->offset = 0;
1100 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1101 MWIFIEX_BD_FLAG_LAST_DESC;
1102 } else {
1103 desc = card->txbd_ring[wrindx];
1104 desc->paddr = buf_pa;
1105 desc->len = (u16)skb->len;
1106 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1107 MWIFIEX_BD_FLAG_LAST_DESC;
1108 }
1109
1110 switch (card->dev->device) {
1111 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1112 card->txbd_wrptr++;
1113 break;
1114 case PCIE_DEVICE_ID_MARVELL_88W8897:
1115 card->txbd_wrptr += reg->ring_tx_start_ptr;
1116 break;
1117 }
1118
1119 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001120 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001121 reg->tx_rollover_ind) ^
1122 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001123
Avinash Patilca8f2112013-02-08 18:18:09 -08001124 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001125 /* Write the TX ring write pointer in to reg->tx_wrptr */
1126 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001127 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001128 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001129 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001130 ret = -1;
1131 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001132 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001133 if ((mwifiex_pcie_txbd_not_full(card)) &&
1134 tx_param->next_pkt_len) {
1135 /* have more packets and TxBD still can hold more */
1136 dev_dbg(adapter->dev,
1137 "SEND DATA: delay dnld-rdy interrupt.\n");
1138 adapter->data_sent = false;
1139 } else {
1140 /* Send the TX ready interrupt */
1141 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1142 CPU_INTR_DNLD_RDY)) {
1143 dev_err(adapter->dev,
1144 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1145 ret = -1;
1146 goto done_unmap;
1147 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001148 }
1149 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001150 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001151 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001152 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001153 dev_dbg(adapter->dev,
1154 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001155 adapter->data_sent = true;
1156 /* Send the TX ready interrupt */
1157 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1158 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001159 dev_err(adapter->dev,
1160 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001161 return -EBUSY;
1162 }
1163
Avinash Patile7f767a2013-01-03 21:21:32 -08001164 return -EINPROGRESS;
1165done_unmap:
1166 MWIFIEX_SKB_PACB(skb, &buf_pa);
1167 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1168 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001169 if (reg->pfu_enabled)
1170 memset(desc2, 0, sizeof(*desc2));
1171 else
1172 memset(desc, 0, sizeof(*desc));
1173
Avinash Patile7f767a2013-01-03 21:21:32 -08001174 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001175}
1176
1177/*
1178 * This function handles received buffer ring and
1179 * dispatches packets to upper
1180 */
1181static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1182{
1183 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001184 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001185 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001186 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001187 int ret = 0;
1188 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001189 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001190 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001191
Avinash Patile7f767a2013-01-03 21:21:32 -08001192 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1193 mwifiex_pm_wakeup_card(adapter);
1194
Amitkumar Karward930fae2011-10-11 17:41:21 -07001195 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001196 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001197 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001198 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001199 ret = -1;
1200 goto done;
1201 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001202 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001203
Avinash Patildd04e6a2013-02-08 18:18:06 -08001204 while (((wrptr & reg->rx_mask) !=
1205 (card->rxbd_rdptr & reg->rx_mask)) ||
1206 ((wrptr & reg->rx_rollover_ind) ==
1207 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001208 struct sk_buff *skb_data;
1209 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001210 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001211
Avinash Patildd04e6a2013-02-08 18:18:06 -08001212 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001213 skb_data = card->rx_buf_list[rd_index];
1214
Avinash Patile7f767a2013-01-03 21:21:32 -08001215 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1216 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1217 PCI_DMA_FROMDEVICE);
1218 card->rx_buf_list[rd_index] = NULL;
1219
Amitkumar Karward930fae2011-10-11 17:41:21 -07001220 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001221 * first 2 bytes for len, next 2 bytes is for type
1222 */
1223 pkt_len = *((__le16 *)skb_data->data);
1224 rx_len = le16_to_cpu(pkt_len);
1225 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001226 dev_dbg(adapter->dev,
1227 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1228 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001229 skb_pull(skb_data, INTF_HEADER_LEN);
1230 mwifiex_handle_rx_packet(adapter, skb_data);
1231
1232 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001233 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001234 dev_err(adapter->dev,
1235 "Unable to allocate skb.\n");
1236 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001237 }
1238
Avinash Patile7f767a2013-01-03 21:21:32 -08001239 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1240 MWIFIEX_RX_DATA_BUF_SIZE,
1241 PCI_DMA_FROMDEVICE))
1242 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001243
Avinash Patile7f767a2013-01-03 21:21:32 -08001244 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1245
1246 dev_dbg(adapter->dev,
1247 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1248 skb_tmp, rd_index);
1249 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001250
1251 if (reg->pfu_enabled) {
1252 desc2 = (void *)card->rxbd_ring[rd_index];
1253 desc2->paddr = buf_pa;
1254 desc2->len = skb_tmp->len;
1255 desc2->frag_len = skb_tmp->len;
1256 desc2->offset = 0;
1257 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1258 } else {
1259 desc = card->rxbd_ring[rd_index];
1260 desc->paddr = buf_pa;
1261 desc->len = skb_tmp->len;
1262 desc->flags = 0;
1263 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001264
Avinash Patildd04e6a2013-02-08 18:18:06 -08001265 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001266 MWIFIEX_MAX_TXRX_BD) {
1267 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001268 reg->rx_rollover_ind) ^
1269 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001270 }
1271 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001272 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001273
Avinash Patilca8f2112013-02-08 18:18:09 -08001274 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001275 /* Write the RX ring read pointer in to reg->rx_rdptr */
1276 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001277 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001278 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001279 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001280 ret = -1;
1281 goto done;
1282 }
1283
1284 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001285 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001286 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001287 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001288 ret = -1;
1289 goto done;
1290 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001291 dev_dbg(adapter->dev,
1292 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001293 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001294 }
1295
1296done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001297 return ret;
1298}
1299
1300/*
1301 * This function downloads the boot command to device
1302 */
1303static int
1304mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1305{
Avinash Patilfc331462013-01-03 21:21:30 -08001306 dma_addr_t buf_pa;
1307 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001308 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001309
Avinash Patilfc331462013-01-03 21:21:30 -08001310 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001311 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001312 "Invalid parameter in %s <%p. len %d>\n",
1313 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001314 return -1;
1315 }
1316
Avinash Patilfc331462013-01-03 21:21:30 -08001317 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1318 return -1;
1319
1320 MWIFIEX_SKB_PACB(skb, &buf_pa);
1321
Avinash Patildd04e6a2013-02-08 18:18:06 -08001322 /* Write the lower 32bits of the physical address to low command
1323 * address scratch register
1324 */
1325 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001326 dev_err(adapter->dev,
1327 "%s: failed to write download command to boot code.\n",
1328 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001329 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1330 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001331 return -1;
1332 }
1333
Avinash Patildd04e6a2013-02-08 18:18:06 -08001334 /* Write the upper 32bits of the physical address to high command
1335 * address scratch register
1336 */
1337 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001338 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001339 dev_err(adapter->dev,
1340 "%s: failed to write download command to boot code.\n",
1341 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001342 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1343 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001344 return -1;
1345 }
1346
Avinash Patildd04e6a2013-02-08 18:18:06 -08001347 /* Write the command length to cmd_size scratch register */
1348 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001349 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001350 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001351 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001352 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1353 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__);
Avinash Patilfc331462013-01-03 21:21:30 -08001362 pci_unmap_single(card->dev, buf_pa,
1363 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001364 return -1;
1365 }
1366
1367 return 0;
1368}
1369
Avinash Patilc6d1d872013-01-03 21:21:29 -08001370/* This function init rx port in firmware which in turn enables to receive data
1371 * from device before transmitting any packet.
1372 */
1373static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1374{
1375 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001376 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001377 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001378
Avinash Patildd04e6a2013-02-08 18:18:06 -08001379 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001380 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1381 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001382 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001383 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001384 return -1;
1385 }
1386 return 0;
1387}
1388
1389/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001390 */
1391static int
1392mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1393{
1394 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001395 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001396 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001397 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1398 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001399
1400 if (!(skb->data && skb->len)) {
1401 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001402 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001403 return -1;
1404 }
1405
1406 /* Make sure a command response buffer is available */
1407 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001408 dev_err(adapter->dev,
1409 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001410 return -EBUSY;
1411 }
1412
Avinash Patilfc331462013-01-03 21:21:30 -08001413 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1414 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001415
1416 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001417
1418 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1419 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1420
1421 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1422 return -1;
1423
1424 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001425
1426 /* To send a command, the driver will:
1427 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001428 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001429 2. Ring the door bell (i.e. set the door bell interrupt)
1430
1431 In response to door bell interrupt, the firmware will perform
1432 the DMA of the command packet (first header to obtain the total
1433 length and then rest of the command).
1434 */
1435
1436 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001437 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001438 /* Write the lower 32bits of the cmdrsp buffer physical
1439 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001440 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001441 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001442 dev_err(adapter->dev,
1443 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001444 ret = -1;
1445 goto done;
1446 }
1447 /* Write the upper 32bits of the cmdrsp buffer physical
1448 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001449 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001450 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001451 dev_err(adapter->dev,
1452 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001453 ret = -1;
1454 goto done;
1455 }
1456 }
1457
Avinash Patilfc331462013-01-03 21:21:30 -08001458 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001459 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1460 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1461 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001462 dev_err(adapter->dev,
1463 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001464 ret = -1;
1465 goto done;
1466 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001467 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1468 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001469 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001470 dev_err(adapter->dev,
1471 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001472 ret = -1;
1473 goto done;
1474 }
1475
Avinash Patildd04e6a2013-02-08 18:18:06 -08001476 /* Write the command length to reg->cmd_size */
1477 if (mwifiex_write_reg(adapter, reg->cmd_size,
1478 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001479 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001480 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001481 ret = -1;
1482 goto done;
1483 }
1484
1485 /* Ring the door bell */
1486 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1487 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001488 dev_err(adapter->dev,
1489 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001490 ret = -1;
1491 goto done;
1492 }
1493
1494done:
1495 if (ret)
1496 adapter->cmd_sent = false;
1497
1498 return 0;
1499}
1500
1501/*
1502 * This function handles command complete interrupt
1503 */
1504static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1505{
1506 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001507 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001508 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001509 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001510 u16 rx_len;
1511 __le16 pkt_len;
1512 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001513
1514 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1515
Avinash Patilfc331462013-01-03 21:21:30 -08001516 MWIFIEX_SKB_PACB(skb, &buf_pa);
1517 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1518 PCI_DMA_FROMDEVICE);
1519
1520 pkt_len = *((__le16 *)skb->data);
1521 rx_len = le16_to_cpu(pkt_len);
1522 skb_trim(skb, rx_len);
1523 skb_pull(skb, INTF_HEADER_LEN);
1524
Amitkumar Karward930fae2011-10-11 17:41:21 -07001525 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001526 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001527 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1528 skb->len);
Avinash Patil52301a82013-02-12 14:38:32 -08001529 while (reg->sleep_cookie && (count++ < 10) &&
1530 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001531 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001532 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001533 dev_err(adapter->dev,
1534 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001535 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001536 memcpy(adapter->upld_buf, skb->data,
1537 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001538 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001539 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1540 PCI_DMA_FROMDEVICE))
1541 return -1;
1542
1543 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001544 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001545 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001546 adapter->cmd_resp_received = true;
1547 /* Take the pointer and set it to CMD node and will
1548 return in the response complete callback */
1549 card->cmdrsp_buf = NULL;
1550
1551 /* Clear the cmd-rsp buffer address in scratch registers. This
1552 will prevent firmware from writing to the same response
1553 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001554 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001555 dev_err(adapter->dev,
1556 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001557 return -1;
1558 }
1559 /* Write the upper 32bits of the cmdrsp buffer physical
1560 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001561 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001562 dev_err(adapter->dev,
1563 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001564 return -1;
1565 }
1566 }
1567
1568 return 0;
1569}
1570
1571/*
1572 * Command Response processing complete handler
1573 */
1574static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1575 struct sk_buff *skb)
1576{
1577 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001578 dma_addr_t buf_pa;
1579 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001580
1581 if (skb) {
1582 card->cmdrsp_buf = skb;
1583 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001584 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1585 PCI_DMA_FROMDEVICE))
1586 return -1;
1587 }
1588
1589 skb_tmp = card->cmd_buf;
1590 if (skb_tmp) {
1591 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
Yogesh Ashok Powar7af1ce02013-04-23 16:49:50 -07001592 pci_unmap_single(card->dev, buf_pa, skb_tmp->len,
Avinash Patilfc331462013-01-03 21:21:30 -08001593 PCI_DMA_FROMDEVICE);
1594 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001595 }
1596
1597 return 0;
1598}
1599
1600/*
1601 * This function handles firmware event ready interrupt
1602 */
1603static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1604{
1605 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001606 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001607 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1608 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001609 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001610 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001611
1612 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1613 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001614
1615 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001616 dev_dbg(adapter->dev, "info: Event being processed, "
1617 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001618 return 0;
1619 }
1620
1621 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1622 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1623 return -1;
1624 }
1625
1626 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001627 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001628 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001629 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001630 return -1;
1631 }
1632
1633 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001634 card->evtbd_rdptr, wrptr);
1635 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1636 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001637 ((wrptr & reg->evt_rollover_ind) ==
1638 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001639 struct sk_buff *skb_cmd;
1640 __le16 data_len = 0;
1641 u16 evt_len;
1642
1643 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1644 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001645 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1646 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1647 PCI_DMA_FROMDEVICE);
1648
Amitkumar Karward930fae2011-10-11 17:41:21 -07001649 /* Take the pointer and set it to event pointer in adapter
1650 and will return back after event handling callback */
1651 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001652 desc = card->evtbd_ring[rdptr];
1653 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001654
1655 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1656 adapter->event_cause = event;
1657 /* The first 4bytes will be the event transfer header
1658 len is 2 bytes followed by type which is 2 bytes */
1659 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1660 evt_len = le16_to_cpu(data_len);
1661
1662 skb_pull(skb_cmd, INTF_HEADER_LEN);
1663 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1664
1665 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1666 memcpy(adapter->event_body, skb_cmd->data +
1667 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1668 MWIFIEX_EVENT_HEADER_LEN);
1669
1670 adapter->event_received = true;
1671 adapter->event_skb = skb_cmd;
1672
1673 /* Do not update the event read pointer here, wait till the
1674 buffer is released. This is just to make things simpler,
1675 we need to find a better method of managing these buffers.
1676 */
1677 }
1678
1679 return 0;
1680}
1681
1682/*
1683 * Event processing complete handler
1684 */
1685static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1686 struct sk_buff *skb)
1687{
1688 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001689 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001690 int ret = 0;
1691 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1692 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001693 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001694 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001695
1696 if (!skb)
1697 return 0;
1698
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001699 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001700 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001701 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001702 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001703 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001704
1705 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001706 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001707 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001708 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001709 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001710 }
1711
1712 if (!card->evt_buf_list[rdptr]) {
1713 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001714 if (mwifiex_map_pci_memory(adapter, skb,
1715 MAX_EVENT_SIZE,
1716 PCI_DMA_FROMDEVICE))
1717 return -1;
1718 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001719 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001720 MWIFIEX_SKB_PACB(skb, &buf_pa);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001721 desc = card->evtbd_ring[rdptr];
1722 desc->paddr = buf_pa;
1723 desc->len = (u16)skb->len;
1724 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001725 skb = NULL;
1726 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001727 dev_dbg(adapter->dev,
1728 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1729 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001730 }
1731
1732 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1733 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001734 reg->evt_rollover_ind) ^
1735 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001736 }
1737
1738 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001739 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001740
Avinash Patildd04e6a2013-02-08 18:18:06 -08001741 /* Write the event ring read pointer in to reg->evt_rdptr */
1742 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1743 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001744 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001745 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001746 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001747 }
1748
Amitkumar Karward930fae2011-10-11 17:41:21 -07001749 dev_dbg(adapter->dev, "info: Check Events Again\n");
1750 ret = mwifiex_pcie_process_event_ready(adapter);
1751
1752 return ret;
1753}
1754
1755/*
1756 * This function downloads the firmware to the card.
1757 *
1758 * Firmware is downloaded to the card in blocks. Every block download
1759 * is tested for CRC errors, and retried a number of times before
1760 * returning failure.
1761 */
1762static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1763 struct mwifiex_fw_image *fw)
1764{
1765 int ret;
1766 u8 *firmware = fw->fw_buf;
1767 u32 firmware_len = fw->fw_len;
1768 u32 offset = 0;
1769 struct sk_buff *skb;
1770 u32 txlen, tx_blocks = 0, tries, len;
1771 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001772 dma_addr_t buf_pa;
1773 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001774 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001775
1776 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001777 dev_err(adapter->dev,
1778 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001779 return -1;
1780 }
1781
1782 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001783 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001784
1785 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001786 dev_err(adapter->dev,
1787 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001788 return -1;
1789 }
1790
1791 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1792 if (!skb) {
1793 ret = -ENOMEM;
1794 goto done;
1795 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001796
1797 /* Perform firmware data transfer */
1798 do {
1799 u32 ireg_intr = 0;
1800
1801 /* More data? */
1802 if (offset >= firmware_len)
1803 break;
1804
1805 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001806 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001807 &len);
1808 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001809 dev_warn(adapter->dev,
1810 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001811 goto done;
1812 }
1813 if (len)
1814 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001815 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001816 }
1817
1818 if (!len) {
1819 break;
1820 } else if (len > MWIFIEX_UPLD_SIZE) {
1821 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001822 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001823 ret = -1;
1824 goto done;
1825 }
1826
1827 txlen = len;
1828
1829 if (len & BIT(0)) {
1830 block_retry_cnt++;
1831 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1832 pr_err("FW download failure @ %d, over max "
1833 "retry count\n", offset);
1834 ret = -1;
1835 goto done;
1836 }
1837 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001838 "helper: len = 0x%04X, txlen = %d\n",
1839 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001840 len &= ~BIT(0);
1841 /* Setting this to 0 to resend from same offset */
1842 txlen = 0;
1843 } else {
1844 block_retry_cnt = 0;
1845 /* Set blocksize to transfer - checking for
1846 last block */
1847 if (firmware_len - offset < txlen)
1848 txlen = firmware_len - offset;
1849
1850 dev_dbg(adapter->dev, ".");
1851
Avinash Patildd04e6a2013-02-08 18:18:06 -08001852 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1853 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001854
1855 /* Copy payload to buffer */
1856 memmove(skb->data, &firmware[offset], txlen);
1857 }
1858
1859 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001860 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001861
1862 /* Send the boot command to device */
1863 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001864 dev_err(adapter->dev,
1865 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001866 ret = -1;
1867 goto done;
1868 }
Avinash Patilfc331462013-01-03 21:21:30 -08001869
1870 MWIFIEX_SKB_PACB(skb, &buf_pa);
1871
Amitkumar Karward930fae2011-10-11 17:41:21 -07001872 /* Wait for the command done interrupt */
1873 do {
1874 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1875 &ireg_intr)) {
1876 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001877 "interrupt status during fw dnld.\n",
1878 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001879 pci_unmap_single(card->dev, buf_pa, skb->len,
1880 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001881 ret = -1;
1882 goto done;
1883 }
1884 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1885 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001886
1887 pci_unmap_single(card->dev, buf_pa, skb->len,
1888 PCI_DMA_TODEVICE);
1889
Amitkumar Karward930fae2011-10-11 17:41:21 -07001890 offset += txlen;
1891 } while (true);
1892
1893 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001894 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001895
1896 ret = 0;
1897
1898done:
1899 dev_kfree_skb_any(skb);
1900 return ret;
1901}
1902
1903/*
1904 * This function checks the firmware status in card.
1905 *
1906 * The winner interface is also determined by this function.
1907 */
1908static int
1909mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1910{
1911 int ret = 0;
1912 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001913 struct pcie_service_card *card = adapter->card;
1914 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001915 u32 tries;
1916
1917 /* Mask spurios interrupts */
1918 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001919 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001920 dev_warn(adapter->dev, "Write register failed\n");
1921 return -1;
1922 }
1923
1924 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001925 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1926 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001927 dev_err(adapter->dev,
1928 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001929 return -1;
1930 }
1931
1932 /* Wait for firmware initialization event */
1933 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001934 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001935 &firmware_stat))
1936 ret = -1;
1937 else
1938 ret = 0;
1939 if (ret)
1940 continue;
1941 if (firmware_stat == FIRMWARE_READY_PCIE) {
1942 ret = 0;
1943 break;
1944 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07001945 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001946 ret = -1;
1947 }
1948 }
1949
1950 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001951 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001952 &winner_status))
1953 ret = -1;
1954 else if (!winner_status) {
1955 dev_err(adapter->dev, "PCI-E is the winner\n");
1956 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001957 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001958 dev_err(adapter->dev,
1959 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1960 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001961 }
1962 }
1963
1964 return ret;
1965}
1966
1967/*
1968 * This function reads the interrupt status from card.
1969 */
1970static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1971{
1972 u32 pcie_ireg;
1973 unsigned long flags;
1974
1975 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1976 return;
1977
1978 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1979 dev_warn(adapter->dev, "Read register failed\n");
1980 return;
1981 }
1982
1983 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1984
1985 mwifiex_pcie_disable_host_int(adapter);
1986
1987 /* Clear the pending interrupts */
1988 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1989 ~pcie_ireg)) {
1990 dev_warn(adapter->dev, "Write register failed\n");
1991 return;
1992 }
1993 spin_lock_irqsave(&adapter->int_lock, flags);
1994 adapter->int_status |= pcie_ireg;
1995 spin_unlock_irqrestore(&adapter->int_lock, flags);
1996
1997 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1998 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1999 (adapter->ps_state == PS_STATE_SLEEP)) {
2000 mwifiex_pcie_enable_host_int(adapter);
2001 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002002 PCIE_CPU_INT_EVENT,
2003 CPU_INTR_SLEEP_CFM_DONE)
2004 ) {
2005 dev_warn(adapter->dev,
2006 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002007 return;
2008
2009 }
2010 }
2011 } else if (!adapter->pps_uapsd_mode &&
Avinash Patilc24d9922013-03-22 21:49:06 -07002012 adapter->ps_state == PS_STATE_SLEEP &&
2013 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002014 /* Potentially for PCIe we could get other
2015 * interrupts like shared. Don't change power
2016 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002017 adapter->ps_state = PS_STATE_AWAKE;
2018 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002019 }
2020 }
2021}
2022
2023/*
2024 * Interrupt handler for PCIe root port
2025 *
2026 * This function reads the interrupt status from firmware and assigns
2027 * the main process in workqueue which will handle the interrupt.
2028 */
2029static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2030{
2031 struct pci_dev *pdev = (struct pci_dev *)context;
2032 struct pcie_service_card *card;
2033 struct mwifiex_adapter *adapter;
2034
2035 if (!pdev) {
2036 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2037 goto exit;
2038 }
2039
2040 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
2041 if (!card || !card->adapter) {
2042 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002043 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002044 goto exit;
2045 }
2046 adapter = card->adapter;
2047
2048 if (adapter->surprise_removed)
2049 goto exit;
2050
2051 mwifiex_interrupt_status(adapter);
2052 queue_work(adapter->workqueue, &adapter->main_work);
2053
2054exit:
2055 return IRQ_HANDLED;
2056}
2057
2058/*
2059 * This function checks the current interrupt status.
2060 *
2061 * The following interrupts are checked and handled by this function -
2062 * - Data sent
2063 * - Command sent
2064 * - Command received
2065 * - Packets received
2066 * - Events received
2067 *
2068 * In case of Rx packets received, the packets are uploaded from card to
2069 * host and processed accordingly.
2070 */
2071static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2072{
2073 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002074 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002075 unsigned long flags;
2076
2077 spin_lock_irqsave(&adapter->int_lock, flags);
2078 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002079 pcie_ireg = adapter->int_status;
2080 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002081 spin_unlock_irqrestore(&adapter->int_lock, flags);
2082
Avinash Patil659c4782013-01-03 21:21:28 -08002083 while (pcie_ireg & HOST_INTR_MASK) {
2084 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2085 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002086 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2087 ret = mwifiex_pcie_send_data_complete(adapter);
2088 if (ret)
2089 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002090 }
Avinash Patil659c4782013-01-03 21:21:28 -08002091 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2092 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002093 dev_dbg(adapter->dev, "info: Rx DATA\n");
2094 ret = mwifiex_pcie_process_recv_data(adapter);
2095 if (ret)
2096 return ret;
2097 }
Avinash Patil659c4782013-01-03 21:21:28 -08002098 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2099 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002100 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2101 ret = mwifiex_pcie_process_event_ready(adapter);
2102 if (ret)
2103 return ret;
2104 }
2105
Avinash Patil659c4782013-01-03 21:21:28 -08002106 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2107 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002108 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002109 dev_dbg(adapter->dev,
2110 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002111 adapter->cmd_sent = false;
2112 }
2113 /* Handle command response */
2114 ret = mwifiex_pcie_process_cmd_complete(adapter);
2115 if (ret)
2116 return ret;
2117 }
2118
2119 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2120 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2121 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002122 dev_warn(adapter->dev,
2123 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002124 return -1;
2125 }
2126
2127 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2128 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002129 PCIE_HOST_INT_STATUS,
2130 ~pcie_ireg)) {
2131 dev_warn(adapter->dev,
2132 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002133 return -1;
2134 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002135 }
2136
2137 }
2138 }
2139 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002140 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002141 if (adapter->ps_state != PS_STATE_SLEEP)
2142 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002143
2144 return 0;
2145}
2146
2147/*
2148 * This function downloads data from driver to card.
2149 *
2150 * Both commands and data packets are transferred to the card by this
2151 * function.
2152 *
2153 * This function adds the PCIE specific header to the front of the buffer
2154 * before transferring. The header contains the length of the packet and
2155 * the type. The firmware handles the packets based upon this set type.
2156 */
2157static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2158 struct sk_buff *skb,
2159 struct mwifiex_tx_param *tx_param)
2160{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002161 if (!skb) {
2162 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002163 return -1;
2164 }
2165
2166 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002167 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002168 else if (type == MWIFIEX_TYPE_CMD)
2169 return mwifiex_pcie_send_cmd(adapter, skb);
2170
2171 return 0;
2172}
2173
2174/*
2175 * This function initializes the PCI-E host memory space, WCB rings, etc.
2176 *
2177 * The following initializations steps are followed -
2178 * - Allocate TXBD ring buffers
2179 * - Allocate RXBD ring buffers
2180 * - Allocate event BD ring buffers
2181 * - Allocate command response ring buffer
2182 * - Allocate sleep cookie buffer
2183 */
2184static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2185{
2186 struct pcie_service_card *card = adapter->card;
2187 int ret;
2188 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002189 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002190
2191 pci_set_drvdata(pdev, card);
2192
2193 ret = pci_enable_device(pdev);
2194 if (ret)
2195 goto err_enable_dev;
2196
2197 pci_set_master(pdev);
2198
2199 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2200 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2201 if (ret) {
2202 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2203 goto err_set_dma_mask;
2204 }
2205
2206 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2207 if (ret) {
2208 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2209 goto err_set_dma_mask;
2210 }
2211
2212 ret = pci_request_region(pdev, 0, DRV_NAME);
2213 if (ret) {
2214 dev_err(adapter->dev, "req_reg(0) error\n");
2215 goto err_req_region0;
2216 }
2217 card->pci_mmap = pci_iomap(pdev, 0, 0);
2218 if (!card->pci_mmap) {
2219 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002220 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002221 goto err_iomap0;
2222 }
2223 ret = pci_request_region(pdev, 2, DRV_NAME);
2224 if (ret) {
2225 dev_err(adapter->dev, "req_reg(2) error\n");
2226 goto err_req_region2;
2227 }
2228 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2229 if (!card->pci_mmap1) {
2230 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002231 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002232 goto err_iomap2;
2233 }
2234
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002235 dev_dbg(adapter->dev,
2236 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2237 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002238
2239 card->cmdrsp_buf = NULL;
2240 ret = mwifiex_pcie_create_txbd_ring(adapter);
2241 if (ret)
2242 goto err_cre_txbd;
2243 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2244 if (ret)
2245 goto err_cre_rxbd;
2246 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2247 if (ret)
2248 goto err_cre_evtbd;
2249 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2250 if (ret)
2251 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002252 if (reg->sleep_cookie) {
2253 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2254 if (ret)
2255 goto err_alloc_cookie;
2256 } else {
2257 card->sleep_cookie_vbase = NULL;
2258 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002259 return ret;
2260
2261err_alloc_cookie:
2262 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2263err_alloc_cmdbuf:
2264 mwifiex_pcie_delete_evtbd_ring(adapter);
2265err_cre_evtbd:
2266 mwifiex_pcie_delete_rxbd_ring(adapter);
2267err_cre_rxbd:
2268 mwifiex_pcie_delete_txbd_ring(adapter);
2269err_cre_txbd:
2270 pci_iounmap(pdev, card->pci_mmap1);
2271err_iomap2:
2272 pci_release_region(pdev, 2);
2273err_req_region2:
2274 pci_iounmap(pdev, card->pci_mmap);
2275err_iomap0:
2276 pci_release_region(pdev, 0);
2277err_req_region0:
2278err_set_dma_mask:
2279 pci_disable_device(pdev);
2280err_enable_dev:
2281 pci_set_drvdata(pdev, NULL);
2282 return ret;
2283}
2284
2285/*
2286 * This function cleans up the allocated card buffers.
2287 *
2288 * The following are freed by this function -
2289 * - TXBD ring buffers
2290 * - RXBD ring buffers
2291 * - Event BD ring buffers
2292 * - Command response ring buffer
2293 * - Sleep cookie buffer
2294 */
2295static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2296{
2297 struct pcie_service_card *card = adapter->card;
2298 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002299 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002300
Amitkumar Karward930fae2011-10-11 17:41:21 -07002301 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002302 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002303 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002304 dev_err(adapter->dev,
2305 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002306 }
2307
2308 if (pdev) {
2309 pci_iounmap(pdev, card->pci_mmap);
2310 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002311 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002312 pci_release_region(pdev, 2);
2313 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002314 pci_set_drvdata(pdev, NULL);
2315 }
2316}
2317
2318/*
2319 * This function registers the PCIE device.
2320 *
2321 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2322 */
2323static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2324{
2325 int ret;
2326 struct pcie_service_card *card = adapter->card;
2327 struct pci_dev *pdev = card->dev;
2328
2329 /* save adapter pointer in card */
2330 card->adapter = adapter;
2331
2332 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2333 "MRVL_PCIE", pdev);
2334 if (ret) {
2335 pr_err("request_irq failed: ret=%d\n", ret);
2336 adapter->card = NULL;
2337 return -1;
2338 }
2339
2340 adapter->dev = &pdev->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002341 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002342
2343 return 0;
2344}
2345
2346/*
2347 * This function unregisters the PCIE device.
2348 *
2349 * The PCIE IRQ is released, the function is disabled and driver
2350 * data is set to null.
2351 */
2352static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2353{
2354 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002355 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002356
2357 if (card) {
2358 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2359 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002360
Avinash Patil52301a82013-02-12 14:38:32 -08002361 reg = card->pcie.reg;
2362 if (reg->sleep_cookie)
2363 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2364
Avinash Patilfc331462013-01-03 21:21:30 -08002365 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2366 mwifiex_pcie_delete_evtbd_ring(adapter);
2367 mwifiex_pcie_delete_rxbd_ring(adapter);
2368 mwifiex_pcie_delete_txbd_ring(adapter);
2369 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002370 }
2371}
2372
2373static struct mwifiex_if_ops pcie_ops = {
2374 .init_if = mwifiex_pcie_init,
2375 .cleanup_if = mwifiex_pcie_cleanup,
2376 .check_fw_status = mwifiex_check_fw_status,
2377 .prog_fw = mwifiex_prog_fw_w_helper,
2378 .register_dev = mwifiex_register_dev,
2379 .unregister_dev = mwifiex_unregister_dev,
2380 .enable_int = mwifiex_pcie_enable_host_int,
2381 .process_int_status = mwifiex_process_int_status,
2382 .host_to_card = mwifiex_pcie_host_to_card,
2383 .wakeup = mwifiex_pm_wakeup_card,
2384 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2385
2386 /* PCIE specific */
2387 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2388 .event_complete = mwifiex_pcie_event_complete,
2389 .update_mp_end_port = NULL,
2390 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002391 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002392 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002393};
2394
2395/*
2396 * This function initializes the PCIE driver module.
2397 *
2398 * This initiates the semaphore and registers the device with
2399 * PCIE bus.
2400 */
2401static int mwifiex_pcie_init_module(void)
2402{
2403 int ret;
2404
Avinash Patilca8f2112013-02-08 18:18:09 -08002405 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002406
2407 sema_init(&add_remove_card_sem, 1);
2408
2409 /* Clear the flag in case user removes the card. */
2410 user_rmmod = 0;
2411
2412 ret = pci_register_driver(&mwifiex_pcie);
2413 if (ret)
2414 pr_err("Driver register failed!\n");
2415 else
2416 pr_debug("info: Driver registered successfully!\n");
2417
2418 return ret;
2419}
2420
2421/*
2422 * This function cleans up the PCIE driver.
2423 *
2424 * The following major steps are followed for cleanup -
2425 * - Resume the device if its suspended
2426 * - Disconnect the device if connected
2427 * - Shutdown the firmware
2428 * - Unregister the device from PCIE bus.
2429 */
2430static void mwifiex_pcie_cleanup_module(void)
2431{
2432 if (!down_interruptible(&add_remove_card_sem))
2433 up(&add_remove_card_sem);
2434
2435 /* Set the flag as user is removing this module. */
2436 user_rmmod = 1;
2437
2438 pci_unregister_driver(&mwifiex_pcie);
2439}
2440
2441module_init(mwifiex_pcie_init_module);
2442module_exit(mwifiex_pcie_cleanup_module);
2443
2444MODULE_AUTHOR("Marvell International Ltd.");
2445MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2446MODULE_VERSION(PCIE_VERSION);
2447MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002448MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2449MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);