blob: 7fe7b53fb17a28d75cb7fa9a6fc315c9f0ddd937 [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) {
Jingoo Hanb2a31202013-09-09 14:26:51 +090096 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -080097 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) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900131 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800132 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);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700235}
236
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700237static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
238{
239 user_rmmod = 1;
240 mwifiex_pcie_remove(pdev);
241
242 return;
243}
244
Amitkumar Karward930fae2011-10-11 17:41:21 -0700245static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
246 {
247 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
248 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800249 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700250 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800251 {
252 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
253 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
254 .driver_data = (unsigned long) &mwifiex_pcie8897,
255 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700256 {},
257};
258
259MODULE_DEVICE_TABLE(pci, mwifiex_ids);
260
Shuah Khan3266d732013-07-03 10:47:10 -0600261#ifdef CONFIG_PM_SLEEP
262/* Power Management Hooks */
263static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
264 mwifiex_pcie_resume);
265#endif
266
Amitkumar Karward930fae2011-10-11 17:41:21 -0700267/* PCI Device Driver */
268static struct pci_driver __refdata mwifiex_pcie = {
269 .name = "mwifiex_pcie",
270 .id_table = mwifiex_ids,
271 .probe = mwifiex_pcie_probe,
272 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600273#ifdef CONFIG_PM_SLEEP
274 .driver = {
275 .pm = &mwifiex_pcie_pm_ops,
276 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700277#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700278 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700279};
280
281/*
282 * This function writes data into PCIE card register.
283 */
284static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
285{
286 struct pcie_service_card *card = adapter->card;
287
288 iowrite32(data, card->pci_mmap1 + reg);
289
290 return 0;
291}
292
293/*
294 * This function reads data from PCIE card register.
295 */
296static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
297{
298 struct pcie_service_card *card = adapter->card;
299
300 *data = ioread32(card->pci_mmap1 + reg);
301
302 return 0;
303}
304
305/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700306 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700307 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700308static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700309{
310 int i = 0;
311
Avinash Patilc0880a22013-03-22 21:49:07 -0700312 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700313 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700314 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700315 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800316 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700317 break;
318 }
319
Avinash Patilc0880a22013-03-22 21:49:07 -0700320 return;
321}
322
323/* This function wakes up the card by reading fw_status register. */
324static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
325{
326 u32 fw_status;
327 struct pcie_service_card *card = adapter->card;
328 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
329
Amitkumar Karward930fae2011-10-11 17:41:21 -0700330 dev_dbg(adapter->dev, "event: Wakeup device...\n");
331
Avinash Patilc0880a22013-03-22 21:49:07 -0700332 if (reg->sleep_cookie)
333 mwifiex_pcie_dev_wakeup_delay(adapter);
334
335 /* Reading fw_status register will wakeup device */
336 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
337 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700338 return -1;
339 }
340
Avinash Patilc0880a22013-03-22 21:49:07 -0700341 if (reg->sleep_cookie) {
342 mwifiex_pcie_dev_wakeup_delay(adapter);
343 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
344 adapter->ps_state = PS_STATE_AWAKE;
345 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700346
347 return 0;
348}
349
350/*
351 * This function is called after the card has woken up.
352 *
353 * The card configuration register is reset.
354 */
355static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
356{
357 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
358
359 return 0;
360}
361
362/*
363 * This function disables the host interrupt.
364 *
365 * The host interrupt mask is read, the disable bit is reset and
366 * written back to the card host interrupt mask register.
367 */
368static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
369{
370 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
371 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
372 0x00000000)) {
373 dev_warn(adapter->dev, "Disable host interrupt failed\n");
374 return -1;
375 }
376 }
377
378 return 0;
379}
380
381/*
382 * This function enables the host interrupt.
383 *
384 * The host interrupt enable mask is written to the card
385 * host interrupt mask register.
386 */
387static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
388{
389 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
390 /* Simply write the mask to the register */
391 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
392 HOST_INTR_MASK)) {
393 dev_warn(adapter->dev, "Enable host interrupt failed\n");
394 return -1;
395 }
396 }
397
398 return 0;
399}
400
401/*
Avinash Patil07324842013-02-08 18:18:07 -0800402 * This function initializes TX buffer ring descriptors
403 */
404static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
405{
406 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800407 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800408 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800409 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800410 int i;
411
412 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
413 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800414 if (reg->pfu_enabled) {
415 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
416 (sizeof(*desc2) * i);
417 desc2 = card->txbd_ring[i];
418 memset(desc2, 0, sizeof(*desc2));
419 } else {
420 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
421 (sizeof(*desc) * i);
422 desc = card->txbd_ring[i];
423 memset(desc, 0, sizeof(*desc));
424 }
Avinash Patil07324842013-02-08 18:18:07 -0800425 }
426
427 return 0;
428}
429
430/* This function initializes RX buffer ring descriptors. Each SKB is allocated
431 * here and after mapping PCI memory, its physical address is assigned to
432 * PCIE Rx buffer descriptor's physical address.
433 */
434static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
435{
436 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800437 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800438 struct sk_buff *skb;
439 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800440 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800441 dma_addr_t buf_pa;
442 int i;
443
444 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
445 /* Allocate skb here so that firmware can DMA data from it */
446 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
447 if (!skb) {
448 dev_err(adapter->dev,
449 "Unable to allocate skb for RX ring.\n");
450 kfree(card->rxbd_ring_vbase);
451 return -ENOMEM;
452 }
453
454 if (mwifiex_map_pci_memory(adapter, skb,
455 MWIFIEX_RX_DATA_BUF_SIZE,
456 PCI_DMA_FROMDEVICE))
457 return -1;
458
459 MWIFIEX_SKB_PACB(skb, &buf_pa);
460
461 dev_dbg(adapter->dev,
462 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
463 skb, skb->len, skb->data, (u32)buf_pa,
464 (u32)((u64)buf_pa >> 32));
465
466 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800467 if (reg->pfu_enabled) {
468 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
469 (sizeof(*desc2) * i);
470 desc2 = card->rxbd_ring[i];
471 desc2->paddr = buf_pa;
472 desc2->len = (u16)skb->len;
473 desc2->frag_len = (u16)skb->len;
474 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
475 desc2->offset = 0;
476 } else {
477 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
478 (sizeof(*desc) * i));
479 desc = card->rxbd_ring[i];
480 desc->paddr = buf_pa;
481 desc->len = (u16)skb->len;
482 desc->flags = 0;
483 }
Avinash Patil07324842013-02-08 18:18:07 -0800484 }
485
486 return 0;
487}
488
489/* This function initializes event buffer ring descriptors. Each SKB is
490 * allocated here and after mapping PCI memory, its physical address is assigned
491 * to PCIE Rx buffer descriptor's physical address
492 */
493static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
494{
495 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800496 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800497 struct sk_buff *skb;
498 dma_addr_t buf_pa;
499 int i;
500
501 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
502 /* Allocate skb here so that firmware can DMA data from it */
503 skb = dev_alloc_skb(MAX_EVENT_SIZE);
504 if (!skb) {
505 dev_err(adapter->dev,
506 "Unable to allocate skb for EVENT buf.\n");
507 kfree(card->evtbd_ring_vbase);
508 return -ENOMEM;
509 }
510 skb_put(skb, MAX_EVENT_SIZE);
511
512 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
513 PCI_DMA_FROMDEVICE))
514 return -1;
515
516 MWIFIEX_SKB_PACB(skb, &buf_pa);
517
518 dev_dbg(adapter->dev,
519 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
520 skb, skb->len, skb->data, (u32)buf_pa,
521 (u32)((u64)buf_pa >> 32));
522
523 card->evt_buf_list[i] = skb;
524 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
525 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800526 desc = card->evtbd_ring[i];
527 desc->paddr = buf_pa;
528 desc->len = (u16)skb->len;
529 desc->flags = 0;
530 }
531
532 return 0;
533}
534
535/* This function cleans up TX buffer rings. If any of the buffer list has valid
536 * SKB address, associated SKB is freed.
537 */
538static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
539{
540 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800541 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800542 struct sk_buff *skb;
543 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800544 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800545 int i;
546
547 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800548 if (reg->pfu_enabled) {
549 desc2 = card->txbd_ring[i];
550 if (card->tx_buf_list[i]) {
551 skb = card->tx_buf_list[i];
552 pci_unmap_single(card->dev, desc2->paddr,
553 skb->len, PCI_DMA_TODEVICE);
554 dev_kfree_skb_any(skb);
555 }
556 memset(desc2, 0, sizeof(*desc2));
557 } else {
558 desc = card->txbd_ring[i];
559 if (card->tx_buf_list[i]) {
560 skb = card->tx_buf_list[i];
561 pci_unmap_single(card->dev, desc->paddr,
562 skb->len, PCI_DMA_TODEVICE);
563 dev_kfree_skb_any(skb);
564 }
565 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800566 }
567 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800568 }
569
570 return;
571}
572
573/* This function cleans up RX buffer rings. If any of the buffer list has valid
574 * SKB address, associated SKB is freed.
575 */
576static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
577{
578 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800579 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800580 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800581 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800582 struct sk_buff *skb;
583 int i;
584
585 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800586 if (reg->pfu_enabled) {
587 desc2 = card->rxbd_ring[i];
588 if (card->rx_buf_list[i]) {
589 skb = card->rx_buf_list[i];
590 pci_unmap_single(card->dev, desc2->paddr,
Avinash Patild033d3a2013-04-19 17:44:42 -0700591 skb->len, PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800592 dev_kfree_skb_any(skb);
593 }
594 memset(desc2, 0, sizeof(*desc2));
595 } else {
596 desc = card->rxbd_ring[i];
597 if (card->rx_buf_list[i]) {
598 skb = card->rx_buf_list[i];
599 pci_unmap_single(card->dev, desc->paddr,
Avinash Patild033d3a2013-04-19 17:44:42 -0700600 skb->len, PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800601 dev_kfree_skb_any(skb);
602 }
603 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800604 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800605 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800606 }
607
608 return;
609}
610
611/* This function cleans up event buffer rings. If any of the buffer list has
612 * valid SKB address, associated SKB is freed.
613 */
614static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
615{
616 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800617 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800618 struct sk_buff *skb;
619 int i;
620
621 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
622 desc = card->evtbd_ring[i];
623 if (card->evt_buf_list[i]) {
624 skb = card->evt_buf_list[i];
625 pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE,
626 PCI_DMA_FROMDEVICE);
627 dev_kfree_skb_any(skb);
628 }
629 card->evt_buf_list[i] = NULL;
630 memset(desc, 0, sizeof(*desc));
631 }
632
633 return;
634}
635
636/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700637 */
638static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
639{
640 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800641 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700642
643 /*
644 * driver maintaines the write pointer and firmware maintaines the read
645 * pointer. The write pointer starts at 0 (zero) while the read pointer
646 * starts at zero with rollover bit set
647 */
648 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800649
650 if (reg->pfu_enabled)
651 card->txbd_rdptr = 0;
652 else
653 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700654
655 /* allocate shared memory for the BD ring and divide the same in to
656 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800657 if (reg->pfu_enabled)
658 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
659 MWIFIEX_MAX_TXRX_BD;
660 else
661 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
662 MWIFIEX_MAX_TXRX_BD;
663
Amitkumar Karward930fae2011-10-11 17:41:21 -0700664 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700665 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800666 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
667 card->txbd_ring_size,
668 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700669 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800670 dev_err(adapter->dev,
671 "allocate consistent memory (%d bytes) failed!\n",
672 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800673 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700674 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700675 dev_dbg(adapter->dev,
676 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800677 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700678 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700679
Avinash Patil07324842013-02-08 18:18:07 -0800680 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700681}
682
683static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
684{
685 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800686 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700687
Avinash Patil07324842013-02-08 18:18:07 -0800688 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700689
Avinash Patilfc331462013-01-03 21:21:30 -0800690 if (card->txbd_ring_vbase)
691 pci_free_consistent(card->dev, card->txbd_ring_size,
692 card->txbd_ring_vbase,
693 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700694 card->txbd_ring_size = 0;
695 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800696 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700697 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800698 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700699
700 return 0;
701}
702
703/*
704 * This function creates buffer descriptor ring for RX
705 */
706static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
707{
708 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800709 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700710
711 /*
712 * driver maintaines the read pointer and firmware maintaines the write
713 * pointer. The write pointer starts at 0 (zero) while the read pointer
714 * starts at zero with rollover bit set
715 */
716 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800717 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700718
Avinash Patilca8f2112013-02-08 18:18:09 -0800719 if (reg->pfu_enabled)
720 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
721 MWIFIEX_MAX_TXRX_BD;
722 else
723 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
724 MWIFIEX_MAX_TXRX_BD;
725
Amitkumar Karward930fae2011-10-11 17:41:21 -0700726 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700727 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800728 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
729 card->rxbd_ring_size,
730 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700731 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800732 dev_err(adapter->dev,
733 "allocate consistent memory (%d bytes) failed!\n",
734 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800735 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700736 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700737
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700738 dev_dbg(adapter->dev,
739 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
740 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
741 (u32)((u64)card->rxbd_ring_pbase >> 32),
742 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700743
Avinash Patil07324842013-02-08 18:18:07 -0800744 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700745}
746
747/*
748 * This function deletes Buffer descriptor ring for RX
749 */
750static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
751{
752 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800753 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700754
Avinash Patil07324842013-02-08 18:18:07 -0800755 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700756
Avinash Patilfc331462013-01-03 21:21:30 -0800757 if (card->rxbd_ring_vbase)
758 pci_free_consistent(card->dev, card->rxbd_ring_size,
759 card->rxbd_ring_vbase,
760 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700761 card->rxbd_ring_size = 0;
762 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800763 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700764 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800765 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700766
767 return 0;
768}
769
770/*
771 * This function creates buffer descriptor ring for Events
772 */
773static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
774{
775 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800776 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700777
778 /*
779 * driver maintaines the read pointer and firmware maintaines the write
780 * pointer. The write pointer starts at 0 (zero) while the read pointer
781 * starts at zero with rollover bit set
782 */
783 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800784 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700785
Avinash Patile05dc3e2013-02-08 18:18:08 -0800786 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800787 MWIFIEX_MAX_EVT_BD;
788
Amitkumar Karward930fae2011-10-11 17:41:21 -0700789 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700790 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800791 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
792 card->evtbd_ring_size,
793 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700794 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700795 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800796 "allocate consistent memory (%d bytes) failed!\n",
797 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800798 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700799 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700800
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700801 dev_dbg(adapter->dev,
802 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
803 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
804 (u32)((u64)card->evtbd_ring_pbase >> 32),
805 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700806
Avinash Patil07324842013-02-08 18:18:07 -0800807 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700808}
809
810/*
811 * This function deletes Buffer descriptor ring for Events
812 */
813static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
814{
815 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800816 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700817
Avinash Patil07324842013-02-08 18:18:07 -0800818 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700819
Avinash Patilfc331462013-01-03 21:21:30 -0800820 if (card->evtbd_ring_vbase)
821 pci_free_consistent(card->dev, card->evtbd_ring_size,
822 card->evtbd_ring_vbase,
823 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700824 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800825 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700826 card->evtbd_ring_size = 0;
827 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800828 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700829
830 return 0;
831}
832
833/*
834 * This function allocates a buffer for CMDRSP
835 */
836static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
837{
838 struct pcie_service_card *card = adapter->card;
839 struct sk_buff *skb;
840
841 /* Allocate memory for receiving command response data */
842 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
843 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700844 dev_err(adapter->dev,
845 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700846 return -ENOMEM;
847 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700848 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800849 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
850 PCI_DMA_FROMDEVICE))
851 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700852
Avinash Patilfc331462013-01-03 21:21:30 -0800853 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700854
855 return 0;
856}
857
858/*
859 * This function deletes a buffer for CMDRSP
860 */
861static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
862{
863 struct pcie_service_card *card;
Avinash Patilfc331462013-01-03 21:21:30 -0800864 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700865
866 if (!adapter)
867 return 0;
868
869 card = adapter->card;
870
Avinash Patilfc331462013-01-03 21:21:30 -0800871 if (card && card->cmdrsp_buf) {
872 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa);
873 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
874 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700875 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800876 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700877
Avinash Patilfc331462013-01-03 21:21:30 -0800878 if (card && card->cmd_buf) {
879 MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa);
Yogesh Ashok Powar7af1ce02013-04-23 16:49:50 -0700880 pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len,
Avinash Patilfc331462013-01-03 21:21:30 -0800881 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800882 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700883 return 0;
884}
885
886/*
887 * This function allocates a buffer for sleep cookie
888 */
889static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
890{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700891 struct pcie_service_card *card = adapter->card;
892
Avinash Patilfc331462013-01-03 21:21:30 -0800893 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
894 &card->sleep_cookie_pbase);
895 if (!card->sleep_cookie_vbase) {
896 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700897 return -ENOMEM;
898 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700899 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800900 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700901
902 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800903 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700904
905 return 0;
906}
907
908/*
909 * This function deletes buffer for sleep cookie
910 */
911static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
912{
913 struct pcie_service_card *card;
914
915 if (!adapter)
916 return 0;
917
918 card = adapter->card;
919
Avinash Patilfc331462013-01-03 21:21:30 -0800920 if (card && card->sleep_cookie_vbase) {
921 pci_free_consistent(card->dev, sizeof(u32),
922 card->sleep_cookie_vbase,
923 card->sleep_cookie_pbase);
924 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700925 }
926
927 return 0;
928}
929
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800930/* This function flushes the TX buffer descriptor ring
931 * This function defined as handler is also called while cleaning TXRX
932 * during disconnect/ bss stop.
933 */
934static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
935{
936 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800937
Avinash Patil48f4d912013-02-20 21:12:58 -0800938 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800939 card->txbd_flush = 1;
940 /* write pointer already set at last send
941 * send dnld-rdy intr again, wait for completion.
942 */
943 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
944 CPU_INTR_DNLD_RDY)) {
945 dev_err(adapter->dev,
946 "failed to assert dnld-rdy interrupt.\n");
947 return -1;
948 }
949 }
950 return 0;
951}
952
Amitkumar Karward930fae2011-10-11 17:41:21 -0700953/*
Avinash Patile7f767a2013-01-03 21:21:32 -0800954 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -0700955 */
Avinash Patile7f767a2013-01-03 21:21:32 -0800956static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700957{
Avinash Patile7f767a2013-01-03 21:21:32 -0800958 struct sk_buff *skb;
959 dma_addr_t buf_pa;
Avinash Patilca8f2112013-02-08 18:18:09 -0800960 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800961 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800962 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700963 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800964 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700965
966 if (!mwifiex_pcie_ok_to_access_hw(adapter))
967 mwifiex_pm_wakeup_card(adapter);
968
969 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800970 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700971 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800972 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700973 return -1;
974 }
975
Avinash Patile7f767a2013-01-03 21:21:32 -0800976 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
977 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700978
Avinash Patilca8f2112013-02-08 18:18:09 -0800979 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800980 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -0800981 while (((card->txbd_rdptr & reg->tx_mask) !=
982 (rdptr & reg->tx_mask)) ||
983 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
984 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800985 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
986 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -0800987
988 skb = card->tx_buf_list[wrdoneidx];
989 if (skb) {
990 dev_dbg(adapter->dev,
991 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
992 skb, wrdoneidx);
993 MWIFIEX_SKB_PACB(skb, &buf_pa);
994 pci_unmap_single(card->dev, buf_pa, skb->len,
995 PCI_DMA_TODEVICE);
996
997 unmap_count++;
998
999 if (card->txbd_flush)
1000 mwifiex_write_data_complete(adapter, skb, 0,
1001 -1);
1002 else
1003 mwifiex_write_data_complete(adapter, skb, 0, 0);
1004 }
1005
1006 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001007
1008 if (reg->pfu_enabled) {
1009 desc2 = (void *)card->txbd_ring[wrdoneidx];
1010 memset(desc2, 0, sizeof(*desc2));
1011 } else {
1012 desc = card->txbd_ring[wrdoneidx];
1013 memset(desc, 0, sizeof(*desc));
1014 }
1015 switch (card->dev->device) {
1016 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1017 card->txbd_rdptr++;
1018 break;
1019 case PCIE_DEVICE_ID_MARVELL_88W8897:
1020 card->txbd_rdptr += reg->ring_tx_start_ptr;
1021 break;
1022 }
1023
Avinash Patile7f767a2013-01-03 21:21:32 -08001024
Avinash Patildd04e6a2013-02-08 18:18:06 -08001025 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001026 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001027 reg->tx_rollover_ind) ^
1028 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001029 }
1030
1031 if (unmap_count)
1032 adapter->data_sent = false;
1033
1034 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001035 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001036 card->txbd_flush = 0;
1037 else
1038 mwifiex_clean_pcie_ring_buf(adapter);
1039 }
1040
1041 return 0;
1042}
1043
1044/* This function sends data buffer to device. First 4 bytes of payload
1045 * are filled with payload length and payload type. Then this payload
1046 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1047 * Download ready interrupt to FW is deffered if Tx ring is not full and
1048 * additional payload can be accomodated.
1049 */
1050static int
1051mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1052 struct mwifiex_tx_param *tx_param)
1053{
1054 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001055 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001056 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001057 int ret;
1058 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001059 struct mwifiex_pcie_buf_desc *desc = NULL;
1060 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001061 __le16 *tmp;
1062
1063 if (!(skb->data && skb->len)) {
1064 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1065 __func__, skb->data, skb->len);
1066 return -1;
1067 }
1068
1069 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1070 mwifiex_pm_wakeup_card(adapter);
1071
Avinash Patilca8f2112013-02-08 18:18:09 -08001072 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001073 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1074 card->txbd_rdptr, card->txbd_wrptr);
1075 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001076 u8 *payload;
1077
1078 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001079 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001080 tmp = (__le16 *)&payload[0];
1081 *tmp = cpu_to_le16((u16)skb->len);
1082 tmp = (__le16 *)&payload[2];
1083 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001084
1085 if (mwifiex_map_pci_memory(adapter, skb, skb->len ,
1086 PCI_DMA_TODEVICE))
1087 return -1;
1088
Avinash Patilca8f2112013-02-08 18:18:09 -08001089 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001090 MWIFIEX_SKB_PACB(skb, &buf_pa);
1091 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001092
Avinash Patilca8f2112013-02-08 18:18:09 -08001093 if (reg->pfu_enabled) {
1094 desc2 = (void *)card->txbd_ring[wrindx];
1095 desc2->paddr = buf_pa;
1096 desc2->len = (u16)skb->len;
1097 desc2->frag_len = (u16)skb->len;
1098 desc2->offset = 0;
1099 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1100 MWIFIEX_BD_FLAG_LAST_DESC;
1101 } else {
1102 desc = card->txbd_ring[wrindx];
1103 desc->paddr = buf_pa;
1104 desc->len = (u16)skb->len;
1105 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1106 MWIFIEX_BD_FLAG_LAST_DESC;
1107 }
1108
1109 switch (card->dev->device) {
1110 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1111 card->txbd_wrptr++;
1112 break;
1113 case PCIE_DEVICE_ID_MARVELL_88W8897:
1114 card->txbd_wrptr += reg->ring_tx_start_ptr;
1115 break;
1116 }
1117
1118 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001119 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001120 reg->tx_rollover_ind) ^
1121 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001122
Avinash Patilca8f2112013-02-08 18:18:09 -08001123 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001124 /* Write the TX ring write pointer in to reg->tx_wrptr */
1125 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001126 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001127 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001128 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001129 ret = -1;
1130 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001131 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001132 if ((mwifiex_pcie_txbd_not_full(card)) &&
1133 tx_param->next_pkt_len) {
1134 /* have more packets and TxBD still can hold more */
1135 dev_dbg(adapter->dev,
1136 "SEND DATA: delay dnld-rdy interrupt.\n");
1137 adapter->data_sent = false;
1138 } else {
1139 /* Send the TX ready interrupt */
1140 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1141 CPU_INTR_DNLD_RDY)) {
1142 dev_err(adapter->dev,
1143 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1144 ret = -1;
1145 goto done_unmap;
1146 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001147 }
1148 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001149 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001150 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001151 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001152 dev_dbg(adapter->dev,
1153 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001154 adapter->data_sent = true;
1155 /* Send the TX ready interrupt */
1156 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1157 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001158 dev_err(adapter->dev,
1159 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001160 return -EBUSY;
1161 }
1162
Avinash Patile7f767a2013-01-03 21:21:32 -08001163 return -EINPROGRESS;
1164done_unmap:
1165 MWIFIEX_SKB_PACB(skb, &buf_pa);
1166 pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE);
1167 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001168 if (reg->pfu_enabled)
1169 memset(desc2, 0, sizeof(*desc2));
1170 else
1171 memset(desc, 0, sizeof(*desc));
1172
Avinash Patile7f767a2013-01-03 21:21:32 -08001173 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001174}
1175
1176/*
1177 * This function handles received buffer ring and
1178 * dispatches packets to upper
1179 */
1180static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1181{
1182 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001183 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001184 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001185 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001186 int ret = 0;
1187 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001188 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001189 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001190
Avinash Patile7f767a2013-01-03 21:21:32 -08001191 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1192 mwifiex_pm_wakeup_card(adapter);
1193
Amitkumar Karward930fae2011-10-11 17:41:21 -07001194 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001195 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001196 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001197 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001198 ret = -1;
1199 goto done;
1200 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001201 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001202
Avinash Patildd04e6a2013-02-08 18:18:06 -08001203 while (((wrptr & reg->rx_mask) !=
1204 (card->rxbd_rdptr & reg->rx_mask)) ||
1205 ((wrptr & reg->rx_rollover_ind) ==
1206 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001207 struct sk_buff *skb_data;
1208 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001209 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001210
Avinash Patildd04e6a2013-02-08 18:18:06 -08001211 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001212 skb_data = card->rx_buf_list[rd_index];
1213
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001214 /* If skb allocation was failed earlier for Rx packet,
1215 * rx_buf_list[rd_index] would have been left with a NULL.
1216 */
1217 if (!skb_data)
1218 return -ENOMEM;
1219
Avinash Patile7f767a2013-01-03 21:21:32 -08001220 MWIFIEX_SKB_PACB(skb_data, &buf_pa);
1221 pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE,
1222 PCI_DMA_FROMDEVICE);
1223 card->rx_buf_list[rd_index] = NULL;
1224
Amitkumar Karward930fae2011-10-11 17:41:21 -07001225 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001226 * first 2 bytes for len, next 2 bytes is for type
1227 */
1228 pkt_len = *((__le16 *)skb_data->data);
1229 rx_len = le16_to_cpu(pkt_len);
1230 skb_put(skb_data, rx_len);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001231 dev_dbg(adapter->dev,
1232 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1233 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001234 skb_pull(skb_data, INTF_HEADER_LEN);
1235 mwifiex_handle_rx_packet(adapter, skb_data);
1236
1237 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001238 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001239 dev_err(adapter->dev,
1240 "Unable to allocate skb.\n");
1241 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001242 }
1243
Avinash Patile7f767a2013-01-03 21:21:32 -08001244 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1245 MWIFIEX_RX_DATA_BUF_SIZE,
1246 PCI_DMA_FROMDEVICE))
1247 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001248
Avinash Patile7f767a2013-01-03 21:21:32 -08001249 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
1250
1251 dev_dbg(adapter->dev,
1252 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1253 skb_tmp, rd_index);
1254 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001255
1256 if (reg->pfu_enabled) {
1257 desc2 = (void *)card->rxbd_ring[rd_index];
1258 desc2->paddr = buf_pa;
1259 desc2->len = skb_tmp->len;
1260 desc2->frag_len = skb_tmp->len;
1261 desc2->offset = 0;
1262 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1263 } else {
1264 desc = card->rxbd_ring[rd_index];
1265 desc->paddr = buf_pa;
1266 desc->len = skb_tmp->len;
1267 desc->flags = 0;
1268 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001269
Avinash Patildd04e6a2013-02-08 18:18:06 -08001270 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001271 MWIFIEX_MAX_TXRX_BD) {
1272 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001273 reg->rx_rollover_ind) ^
1274 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001275 }
1276 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001277 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001278
Avinash Patilca8f2112013-02-08 18:18:09 -08001279 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001280 /* Write the RX ring read pointer in to reg->rx_rdptr */
1281 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001282 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001283 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001284 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001285 ret = -1;
1286 goto done;
1287 }
1288
1289 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001290 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001291 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001292 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001293 ret = -1;
1294 goto done;
1295 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001296 dev_dbg(adapter->dev,
1297 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001298 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001299 }
1300
1301done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001302 return ret;
1303}
1304
1305/*
1306 * This function downloads the boot command to device
1307 */
1308static int
1309mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1310{
Avinash Patilfc331462013-01-03 21:21:30 -08001311 dma_addr_t buf_pa;
1312 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001313 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001314
Avinash Patilfc331462013-01-03 21:21:30 -08001315 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001316 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001317 "Invalid parameter in %s <%p. len %d>\n",
1318 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001319 return -1;
1320 }
1321
Avinash Patilfc331462013-01-03 21:21:30 -08001322 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1323 return -1;
1324
1325 MWIFIEX_SKB_PACB(skb, &buf_pa);
1326
Avinash Patildd04e6a2013-02-08 18:18:06 -08001327 /* Write the lower 32bits of the physical address to low command
1328 * address scratch register
1329 */
1330 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001331 dev_err(adapter->dev,
1332 "%s: failed to write download command to boot code.\n",
1333 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001334 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1335 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001336 return -1;
1337 }
1338
Avinash Patildd04e6a2013-02-08 18:18:06 -08001339 /* Write the upper 32bits of the physical address to high command
1340 * address scratch register
1341 */
1342 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001343 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001344 dev_err(adapter->dev,
1345 "%s: failed to write download command to boot code.\n",
1346 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001347 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1348 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001349 return -1;
1350 }
1351
Avinash Patildd04e6a2013-02-08 18:18:06 -08001352 /* Write the command length to cmd_size scratch register */
1353 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001354 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001355 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001356 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001357 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1358 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001359 return -1;
1360 }
1361
1362 /* Ring the door bell */
1363 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1364 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001365 dev_err(adapter->dev,
1366 "%s: failed to assert door-bell intr\n", __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001367 pci_unmap_single(card->dev, buf_pa,
1368 MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001369 return -1;
1370 }
1371
1372 return 0;
1373}
1374
Avinash Patilc6d1d872013-01-03 21:21:29 -08001375/* This function init rx port in firmware which in turn enables to receive data
1376 * from device before transmitting any packet.
1377 */
1378static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1379{
1380 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001381 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001382 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001383
Avinash Patildd04e6a2013-02-08 18:18:06 -08001384 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001385 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1386 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001387 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001388 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001389 return -1;
1390 }
1391 return 0;
1392}
1393
1394/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001395 */
1396static int
1397mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1398{
1399 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001400 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001401 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001402 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1403 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001404
1405 if (!(skb->data && skb->len)) {
1406 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001407 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001408 return -1;
1409 }
1410
1411 /* Make sure a command response buffer is available */
1412 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001413 dev_err(adapter->dev,
1414 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001415 return -EBUSY;
1416 }
1417
Avinash Patilfc331462013-01-03 21:21:30 -08001418 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1419 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001420
1421 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001422
1423 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1424 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1425
1426 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1427 return -1;
1428
1429 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001430
1431 /* To send a command, the driver will:
1432 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001433 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001434 2. Ring the door bell (i.e. set the door bell interrupt)
1435
1436 In response to door bell interrupt, the firmware will perform
1437 the DMA of the command packet (first header to obtain the total
1438 length and then rest of the command).
1439 */
1440
1441 if (card->cmdrsp_buf) {
Avinash Patilfc331462013-01-03 21:21:30 -08001442 MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001443 /* Write the lower 32bits of the cmdrsp buffer physical
1444 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001445 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001446 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001447 dev_err(adapter->dev,
1448 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001449 ret = -1;
1450 goto done;
1451 }
1452 /* Write the upper 32bits of the cmdrsp buffer physical
1453 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001454 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001455 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001456 dev_err(adapter->dev,
1457 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001458 ret = -1;
1459 goto done;
1460 }
1461 }
1462
Avinash Patilfc331462013-01-03 21:21:30 -08001463 MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001464 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1465 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1466 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001467 dev_err(adapter->dev,
1468 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001469 ret = -1;
1470 goto done;
1471 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001472 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1473 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001474 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001475 dev_err(adapter->dev,
1476 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001477 ret = -1;
1478 goto done;
1479 }
1480
Avinash Patildd04e6a2013-02-08 18:18:06 -08001481 /* Write the command length to reg->cmd_size */
1482 if (mwifiex_write_reg(adapter, reg->cmd_size,
1483 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001484 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001485 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001486 ret = -1;
1487 goto done;
1488 }
1489
1490 /* Ring the door bell */
1491 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1492 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001493 dev_err(adapter->dev,
1494 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001495 ret = -1;
1496 goto done;
1497 }
1498
1499done:
1500 if (ret)
1501 adapter->cmd_sent = false;
1502
1503 return 0;
1504}
1505
1506/*
1507 * This function handles command complete interrupt
1508 */
1509static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1510{
1511 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001512 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001513 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001514 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001515 u16 rx_len;
1516 __le16 pkt_len;
1517 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001518
1519 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1520
Avinash Patilfc331462013-01-03 21:21:30 -08001521 MWIFIEX_SKB_PACB(skb, &buf_pa);
1522 pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE,
1523 PCI_DMA_FROMDEVICE);
1524
1525 pkt_len = *((__le16 *)skb->data);
1526 rx_len = le16_to_cpu(pkt_len);
1527 skb_trim(skb, rx_len);
1528 skb_pull(skb, INTF_HEADER_LEN);
1529
Amitkumar Karward930fae2011-10-11 17:41:21 -07001530 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001531 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001532 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1533 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001534 mwifiex_pcie_enable_host_int(adapter);
1535 if (mwifiex_write_reg(adapter,
1536 PCIE_CPU_INT_EVENT,
1537 CPU_INTR_SLEEP_CFM_DONE)) {
1538 dev_warn(adapter->dev,
1539 "Write register failed\n");
1540 return -1;
1541 }
Avinash Patil52301a82013-02-12 14:38:32 -08001542 while (reg->sleep_cookie && (count++ < 10) &&
1543 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001544 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001545 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001546 dev_err(adapter->dev,
1547 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001548 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001549 memcpy(adapter->upld_buf, skb->data,
1550 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001551 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001552 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1553 PCI_DMA_FROMDEVICE))
1554 return -1;
1555
1556 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001557 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001558 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001559 adapter->cmd_resp_received = true;
1560 /* Take the pointer and set it to CMD node and will
1561 return in the response complete callback */
1562 card->cmdrsp_buf = NULL;
1563
1564 /* Clear the cmd-rsp buffer address in scratch registers. This
1565 will prevent firmware from writing to the same response
1566 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001567 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001568 dev_err(adapter->dev,
1569 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001570 return -1;
1571 }
1572 /* Write the upper 32bits of the cmdrsp buffer physical
1573 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001574 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001575 dev_err(adapter->dev,
1576 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001577 return -1;
1578 }
1579 }
1580
1581 return 0;
1582}
1583
1584/*
1585 * Command Response processing complete handler
1586 */
1587static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1588 struct sk_buff *skb)
1589{
1590 struct pcie_service_card *card = adapter->card;
Avinash Patilfc331462013-01-03 21:21:30 -08001591 dma_addr_t buf_pa;
1592 struct sk_buff *skb_tmp;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001593
1594 if (skb) {
1595 card->cmdrsp_buf = skb;
1596 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001597 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1598 PCI_DMA_FROMDEVICE))
1599 return -1;
1600 }
1601
1602 skb_tmp = card->cmd_buf;
1603 if (skb_tmp) {
1604 MWIFIEX_SKB_PACB(skb_tmp, &buf_pa);
Yogesh Ashok Powar7af1ce02013-04-23 16:49:50 -07001605 pci_unmap_single(card->dev, buf_pa, skb_tmp->len,
Avinash Patilfc331462013-01-03 21:21:30 -08001606 PCI_DMA_FROMDEVICE);
1607 card->cmd_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001608 }
1609
1610 return 0;
1611}
1612
1613/*
1614 * This function handles firmware event ready interrupt
1615 */
1616static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1617{
1618 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001619 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001620 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1621 u32 wrptr, event;
Avinash Patilfc331462013-01-03 21:21:30 -08001622 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001623 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001624
1625 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1626 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001627
1628 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001629 dev_dbg(adapter->dev, "info: Event being processed, "
1630 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001631 return 0;
1632 }
1633
1634 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1635 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1636 return -1;
1637 }
1638
1639 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001640 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001641 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001642 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001643 return -1;
1644 }
1645
1646 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001647 card->evtbd_rdptr, wrptr);
1648 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1649 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001650 ((wrptr & reg->evt_rollover_ind) ==
1651 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001652 struct sk_buff *skb_cmd;
1653 __le16 data_len = 0;
1654 u16 evt_len;
1655
1656 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1657 skb_cmd = card->evt_buf_list[rdptr];
Avinash Patilfc331462013-01-03 21:21:30 -08001658 MWIFIEX_SKB_PACB(skb_cmd, &buf_pa);
1659 pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE,
1660 PCI_DMA_FROMDEVICE);
1661
Amitkumar Karward930fae2011-10-11 17:41:21 -07001662 /* Take the pointer and set it to event pointer in adapter
1663 and will return back after event handling callback */
1664 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001665 desc = card->evtbd_ring[rdptr];
1666 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001667
1668 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1669 adapter->event_cause = event;
1670 /* The first 4bytes will be the event transfer header
1671 len is 2 bytes followed by type which is 2 bytes */
1672 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1673 evt_len = le16_to_cpu(data_len);
1674
1675 skb_pull(skb_cmd, INTF_HEADER_LEN);
1676 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1677
1678 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1679 memcpy(adapter->event_body, skb_cmd->data +
1680 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1681 MWIFIEX_EVENT_HEADER_LEN);
1682
1683 adapter->event_received = true;
1684 adapter->event_skb = skb_cmd;
1685
1686 /* Do not update the event read pointer here, wait till the
1687 buffer is released. This is just to make things simpler,
1688 we need to find a better method of managing these buffers.
1689 */
1690 }
1691
1692 return 0;
1693}
1694
1695/*
1696 * Event processing complete handler
1697 */
1698static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1699 struct sk_buff *skb)
1700{
1701 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001702 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001703 int ret = 0;
1704 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1705 u32 wrptr;
Avinash Patilfc331462013-01-03 21:21:30 -08001706 dma_addr_t buf_pa;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001707 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001708
1709 if (!skb)
1710 return 0;
1711
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001712 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001713 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001714 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001715 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001716 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001717
1718 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001719 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001720 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001721 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001722 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001723 }
1724
1725 if (!card->evt_buf_list[rdptr]) {
1726 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001727 if (mwifiex_map_pci_memory(adapter, skb,
1728 MAX_EVENT_SIZE,
1729 PCI_DMA_FROMDEVICE))
1730 return -1;
1731 MWIFIEX_SKB_PACB(skb, &buf_pa);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001732 card->evt_buf_list[rdptr] = skb;
Avinash Patilfc331462013-01-03 21:21:30 -08001733 MWIFIEX_SKB_PACB(skb, &buf_pa);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001734 desc = card->evtbd_ring[rdptr];
1735 desc->paddr = buf_pa;
1736 desc->len = (u16)skb->len;
1737 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001738 skb = NULL;
1739 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001740 dev_dbg(adapter->dev,
1741 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1742 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001743 }
1744
1745 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1746 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001747 reg->evt_rollover_ind) ^
1748 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001749 }
1750
1751 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001752 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001753
Avinash Patildd04e6a2013-02-08 18:18:06 -08001754 /* Write the event ring read pointer in to reg->evt_rdptr */
1755 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1756 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001757 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001758 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001759 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001760 }
1761
Amitkumar Karward930fae2011-10-11 17:41:21 -07001762 dev_dbg(adapter->dev, "info: Check Events Again\n");
1763 ret = mwifiex_pcie_process_event_ready(adapter);
1764
1765 return ret;
1766}
1767
1768/*
1769 * This function downloads the firmware to the card.
1770 *
1771 * Firmware is downloaded to the card in blocks. Every block download
1772 * is tested for CRC errors, and retried a number of times before
1773 * returning failure.
1774 */
1775static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1776 struct mwifiex_fw_image *fw)
1777{
1778 int ret;
1779 u8 *firmware = fw->fw_buf;
1780 u32 firmware_len = fw->fw_len;
1781 u32 offset = 0;
1782 struct sk_buff *skb;
1783 u32 txlen, tx_blocks = 0, tries, len;
1784 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001785 dma_addr_t buf_pa;
1786 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001787 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001788
1789 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001790 dev_err(adapter->dev,
1791 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001792 return -1;
1793 }
1794
1795 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001796 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001797
1798 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001799 dev_err(adapter->dev,
1800 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001801 return -1;
1802 }
1803
1804 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1805 if (!skb) {
1806 ret = -ENOMEM;
1807 goto done;
1808 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001809
1810 /* Perform firmware data transfer */
1811 do {
1812 u32 ireg_intr = 0;
1813
1814 /* More data? */
1815 if (offset >= firmware_len)
1816 break;
1817
1818 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001819 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001820 &len);
1821 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001822 dev_warn(adapter->dev,
1823 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001824 goto done;
1825 }
1826 if (len)
1827 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001828 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001829 }
1830
1831 if (!len) {
1832 break;
1833 } else if (len > MWIFIEX_UPLD_SIZE) {
1834 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001835 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001836 ret = -1;
1837 goto done;
1838 }
1839
1840 txlen = len;
1841
1842 if (len & BIT(0)) {
1843 block_retry_cnt++;
1844 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1845 pr_err("FW download failure @ %d, over max "
1846 "retry count\n", offset);
1847 ret = -1;
1848 goto done;
1849 }
1850 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001851 "helper: len = 0x%04X, txlen = %d\n",
1852 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001853 len &= ~BIT(0);
1854 /* Setting this to 0 to resend from same offset */
1855 txlen = 0;
1856 } else {
1857 block_retry_cnt = 0;
1858 /* Set blocksize to transfer - checking for
1859 last block */
1860 if (firmware_len - offset < txlen)
1861 txlen = firmware_len - offset;
1862
1863 dev_dbg(adapter->dev, ".");
1864
Avinash Patildd04e6a2013-02-08 18:18:06 -08001865 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1866 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001867
1868 /* Copy payload to buffer */
1869 memmove(skb->data, &firmware[offset], txlen);
1870 }
1871
1872 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001873 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001874
1875 /* Send the boot command to device */
1876 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001877 dev_err(adapter->dev,
1878 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001879 ret = -1;
1880 goto done;
1881 }
Avinash Patilfc331462013-01-03 21:21:30 -08001882
1883 MWIFIEX_SKB_PACB(skb, &buf_pa);
1884
Amitkumar Karward930fae2011-10-11 17:41:21 -07001885 /* Wait for the command done interrupt */
1886 do {
1887 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1888 &ireg_intr)) {
1889 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001890 "interrupt status during fw dnld.\n",
1891 __func__);
Avinash Patilfc331462013-01-03 21:21:30 -08001892 pci_unmap_single(card->dev, buf_pa, skb->len,
1893 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001894 ret = -1;
1895 goto done;
1896 }
1897 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1898 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001899
1900 pci_unmap_single(card->dev, buf_pa, skb->len,
1901 PCI_DMA_TODEVICE);
1902
Amitkumar Karward930fae2011-10-11 17:41:21 -07001903 offset += txlen;
1904 } while (true);
1905
1906 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001907 offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001908
1909 ret = 0;
1910
1911done:
1912 dev_kfree_skb_any(skb);
1913 return ret;
1914}
1915
1916/*
1917 * This function checks the firmware status in card.
1918 *
1919 * The winner interface is also determined by this function.
1920 */
1921static int
1922mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1923{
1924 int ret = 0;
1925 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001926 struct pcie_service_card *card = adapter->card;
1927 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001928 u32 tries;
1929
1930 /* Mask spurios interrupts */
1931 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001932 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001933 dev_warn(adapter->dev, "Write register failed\n");
1934 return -1;
1935 }
1936
1937 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001938 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1939 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001940 dev_err(adapter->dev,
1941 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001942 return -1;
1943 }
1944
1945 /* Wait for firmware initialization event */
1946 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001947 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001948 &firmware_stat))
1949 ret = -1;
1950 else
1951 ret = 0;
1952 if (ret)
1953 continue;
1954 if (firmware_stat == FIRMWARE_READY_PCIE) {
1955 ret = 0;
1956 break;
1957 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07001958 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001959 ret = -1;
1960 }
1961 }
1962
1963 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001964 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001965 &winner_status))
1966 ret = -1;
1967 else if (!winner_status) {
1968 dev_err(adapter->dev, "PCI-E is the winner\n");
1969 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001970 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001971 dev_err(adapter->dev,
1972 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
1973 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001974 }
1975 }
1976
1977 return ret;
1978}
1979
1980/*
1981 * This function reads the interrupt status from card.
1982 */
1983static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1984{
1985 u32 pcie_ireg;
1986 unsigned long flags;
1987
1988 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1989 return;
1990
1991 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1992 dev_warn(adapter->dev, "Read register failed\n");
1993 return;
1994 }
1995
1996 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1997
1998 mwifiex_pcie_disable_host_int(adapter);
1999
2000 /* Clear the pending interrupts */
2001 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2002 ~pcie_ireg)) {
2003 dev_warn(adapter->dev, "Write register failed\n");
2004 return;
2005 }
2006 spin_lock_irqsave(&adapter->int_lock, flags);
2007 adapter->int_status |= pcie_ireg;
2008 spin_unlock_irqrestore(&adapter->int_lock, flags);
2009
Amitkumar Karwar1c975602014-02-18 15:41:56 -08002010 if (!adapter->pps_uapsd_mode &&
2011 adapter->ps_state == PS_STATE_SLEEP &&
2012 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002013 /* Potentially for PCIe we could get other
2014 * interrupts like shared. Don't change power
2015 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002016 adapter->ps_state = PS_STATE_AWAKE;
2017 adapter->pm_wakeup_fw_try = false;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002018 }
2019 }
2020}
2021
2022/*
2023 * Interrupt handler for PCIe root port
2024 *
2025 * This function reads the interrupt status from firmware and assigns
2026 * the main process in workqueue which will handle the interrupt.
2027 */
2028static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2029{
2030 struct pci_dev *pdev = (struct pci_dev *)context;
2031 struct pcie_service_card *card;
2032 struct mwifiex_adapter *adapter;
2033
2034 if (!pdev) {
2035 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2036 goto exit;
2037 }
2038
Jingoo Hanb2a31202013-09-09 14:26:51 +09002039 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002040 if (!card || !card->adapter) {
2041 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002042 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002043 goto exit;
2044 }
2045 adapter = card->adapter;
2046
2047 if (adapter->surprise_removed)
2048 goto exit;
2049
2050 mwifiex_interrupt_status(adapter);
2051 queue_work(adapter->workqueue, &adapter->main_work);
2052
2053exit:
2054 return IRQ_HANDLED;
2055}
2056
2057/*
2058 * This function checks the current interrupt status.
2059 *
2060 * The following interrupts are checked and handled by this function -
2061 * - Data sent
2062 * - Command sent
2063 * - Command received
2064 * - Packets received
2065 * - Events received
2066 *
2067 * In case of Rx packets received, the packets are uploaded from card to
2068 * host and processed accordingly.
2069 */
2070static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2071{
2072 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002073 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002074 unsigned long flags;
2075
2076 spin_lock_irqsave(&adapter->int_lock, flags);
2077 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002078 pcie_ireg = adapter->int_status;
2079 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002080 spin_unlock_irqrestore(&adapter->int_lock, flags);
2081
Avinash Patil659c4782013-01-03 21:21:28 -08002082 while (pcie_ireg & HOST_INTR_MASK) {
2083 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2084 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002085 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2086 ret = mwifiex_pcie_send_data_complete(adapter);
2087 if (ret)
2088 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002089 }
Avinash Patil659c4782013-01-03 21:21:28 -08002090 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2091 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002092 dev_dbg(adapter->dev, "info: Rx DATA\n");
2093 ret = mwifiex_pcie_process_recv_data(adapter);
2094 if (ret)
2095 return ret;
2096 }
Avinash Patil659c4782013-01-03 21:21:28 -08002097 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2098 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002099 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2100 ret = mwifiex_pcie_process_event_ready(adapter);
2101 if (ret)
2102 return ret;
2103 }
2104
Avinash Patil659c4782013-01-03 21:21:28 -08002105 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2106 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002107 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002108 dev_dbg(adapter->dev,
2109 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002110 adapter->cmd_sent = false;
2111 }
2112 /* Handle command response */
2113 ret = mwifiex_pcie_process_cmd_complete(adapter);
2114 if (ret)
2115 return ret;
2116 }
2117
2118 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2119 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2120 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002121 dev_warn(adapter->dev,
2122 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002123 return -1;
2124 }
2125
2126 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2127 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002128 PCIE_HOST_INT_STATUS,
2129 ~pcie_ireg)) {
2130 dev_warn(adapter->dev,
2131 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002132 return -1;
2133 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002134 }
2135
2136 }
2137 }
2138 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002139 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002140 if (adapter->ps_state != PS_STATE_SLEEP)
2141 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002142
2143 return 0;
2144}
2145
2146/*
2147 * This function downloads data from driver to card.
2148 *
2149 * Both commands and data packets are transferred to the card by this
2150 * function.
2151 *
2152 * This function adds the PCIE specific header to the front of the buffer
2153 * before transferring. The header contains the length of the packet and
2154 * the type. The firmware handles the packets based upon this set type.
2155 */
2156static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2157 struct sk_buff *skb,
2158 struct mwifiex_tx_param *tx_param)
2159{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002160 if (!skb) {
2161 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002162 return -1;
2163 }
2164
2165 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002166 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002167 else if (type == MWIFIEX_TYPE_CMD)
2168 return mwifiex_pcie_send_cmd(adapter, skb);
2169
2170 return 0;
2171}
2172
2173/*
2174 * This function initializes the PCI-E host memory space, WCB rings, etc.
2175 *
2176 * The following initializations steps are followed -
2177 * - Allocate TXBD ring buffers
2178 * - Allocate RXBD ring buffers
2179 * - Allocate event BD ring buffers
2180 * - Allocate command response ring buffer
2181 * - Allocate sleep cookie buffer
2182 */
2183static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2184{
2185 struct pcie_service_card *card = adapter->card;
2186 int ret;
2187 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002188 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002189
2190 pci_set_drvdata(pdev, card);
2191
2192 ret = pci_enable_device(pdev);
2193 if (ret)
2194 goto err_enable_dev;
2195
2196 pci_set_master(pdev);
2197
2198 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2199 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2200 if (ret) {
2201 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2202 goto err_set_dma_mask;
2203 }
2204
2205 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2206 if (ret) {
2207 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2208 goto err_set_dma_mask;
2209 }
2210
2211 ret = pci_request_region(pdev, 0, DRV_NAME);
2212 if (ret) {
2213 dev_err(adapter->dev, "req_reg(0) error\n");
2214 goto err_req_region0;
2215 }
2216 card->pci_mmap = pci_iomap(pdev, 0, 0);
2217 if (!card->pci_mmap) {
2218 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002219 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002220 goto err_iomap0;
2221 }
2222 ret = pci_request_region(pdev, 2, DRV_NAME);
2223 if (ret) {
2224 dev_err(adapter->dev, "req_reg(2) error\n");
2225 goto err_req_region2;
2226 }
2227 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2228 if (!card->pci_mmap1) {
2229 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002230 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002231 goto err_iomap2;
2232 }
2233
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002234 dev_dbg(adapter->dev,
2235 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2236 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002237
2238 card->cmdrsp_buf = NULL;
2239 ret = mwifiex_pcie_create_txbd_ring(adapter);
2240 if (ret)
2241 goto err_cre_txbd;
2242 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2243 if (ret)
2244 goto err_cre_rxbd;
2245 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2246 if (ret)
2247 goto err_cre_evtbd;
2248 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2249 if (ret)
2250 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002251 if (reg->sleep_cookie) {
2252 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2253 if (ret)
2254 goto err_alloc_cookie;
2255 } else {
2256 card->sleep_cookie_vbase = NULL;
2257 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002258 return ret;
2259
2260err_alloc_cookie:
2261 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2262err_alloc_cmdbuf:
2263 mwifiex_pcie_delete_evtbd_ring(adapter);
2264err_cre_evtbd:
2265 mwifiex_pcie_delete_rxbd_ring(adapter);
2266err_cre_rxbd:
2267 mwifiex_pcie_delete_txbd_ring(adapter);
2268err_cre_txbd:
2269 pci_iounmap(pdev, card->pci_mmap1);
2270err_iomap2:
2271 pci_release_region(pdev, 2);
2272err_req_region2:
2273 pci_iounmap(pdev, card->pci_mmap);
2274err_iomap0:
2275 pci_release_region(pdev, 0);
2276err_req_region0:
2277err_set_dma_mask:
2278 pci_disable_device(pdev);
2279err_enable_dev:
2280 pci_set_drvdata(pdev, NULL);
2281 return ret;
2282}
2283
2284/*
2285 * This function cleans up the allocated card buffers.
2286 *
2287 * The following are freed by this function -
2288 * - TXBD ring buffers
2289 * - RXBD ring buffers
2290 * - Event BD ring buffers
2291 * - Command response ring buffer
2292 * - Sleep cookie buffer
2293 */
2294static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2295{
2296 struct pcie_service_card *card = adapter->card;
2297 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002298 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002299
Amitkumar Karward930fae2011-10-11 17:41:21 -07002300 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002301 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002302 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002303 dev_err(adapter->dev,
2304 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002305 }
2306
2307 if (pdev) {
2308 pci_iounmap(pdev, card->pci_mmap);
2309 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002310 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002311 pci_release_region(pdev, 2);
2312 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002313 pci_set_drvdata(pdev, NULL);
2314 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002315 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002316}
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);