blob: a460b0e6a151addaae1f7e265011a562069f72a0 [file] [log] [blame]
Amitkumar Karward930fae2011-10-11 17:41:21 -07001/*
2 * Marvell Wireless LAN device driver: PCIE specific handling
3 *
Xinming Hu65da33f2014-06-19 21:38:57 -07004 * Copyright (C) 2011-2014, Marvell International Ltd.
Amitkumar Karward930fae2011-10-11 17:41:21 -07005 *
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
Amitkumar Karwar92c25382014-06-19 21:38:52 -070040static struct memory_type_mapping mem_type_mapping_tbl[] = {
41 {"ITCM", NULL, 0, 0xF0},
42 {"DTCM", NULL, 0, 0xF1},
43 {"SQRAM", NULL, 0, 0xF2},
44 {"IRAM", NULL, 0, 0xF3},
Amitkumar Karwar7e174832014-09-18 07:18:50 -040045 {"APU", NULL, 0, 0xF4},
46 {"CIU", NULL, 0, 0xF5},
47 {"ICU", NULL, 0, 0xF6},
48 {"MAC", NULL, 0, 0xF7},
Amitkumar Karwar92c25382014-06-19 21:38:52 -070049};
50
Avinash Patilfc331462013-01-03 21:21:30 -080051static int
52mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
Aaron Durbindbccc922014-02-07 16:25:50 -080053 size_t size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070054{
Avinash Patilfc331462013-01-03 21:21:30 -080055 struct pcie_service_card *card = adapter->card;
Aaron Durbindbccc922014-02-07 16:25:50 -080056 struct mwifiex_dma_mapping mapping;
Amitkumar Karward930fae2011-10-11 17:41:21 -070057
Aaron Durbindbccc922014-02-07 16:25:50 -080058 mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
59 if (pci_dma_mapping_error(card->dev, mapping.addr)) {
Avinash Patilfc331462013-01-03 21:21:30 -080060 dev_err(adapter->dev, "failed to map pci memory!\n");
61 return -1;
62 }
Aaron Durbindbccc922014-02-07 16:25:50 -080063 mapping.len = size;
Chin-Ran Lobca463e2014-06-06 19:37:10 -070064 mwifiex_store_mapping(skb, &mapping);
Avinash Patilfc331462013-01-03 21:21:30 -080065 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070066}
67
Aaron Durbindbccc922014-02-07 16:25:50 -080068static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
69 struct sk_buff *skb, int flags)
70{
71 struct pcie_service_card *card = adapter->card;
72 struct mwifiex_dma_mapping mapping;
73
Chin-Ran Lobca463e2014-06-06 19:37:10 -070074 mwifiex_get_mapping(skb, &mapping);
Aaron Durbindbccc922014-02-07 16:25:50 -080075 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
76}
77
Amitkumar Karward930fae2011-10-11 17:41:21 -070078/*
79 * This function reads sleep cookie and checks if FW is ready
80 */
81static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
82{
83 u32 *cookie_addr;
84 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080085 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
86
87 if (!reg->sleep_cookie)
88 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070089
Avinash Patilfc331462013-01-03 21:21:30 -080090 if (card->sleep_cookie_vbase) {
91 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070092 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
93 *cookie_addr);
94 if (*cookie_addr == FW_AWAKE_COOKIE)
95 return true;
96 }
97
98 return false;
99}
100
Shuah Khan3266d732013-07-03 10:47:10 -0600101#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700102/*
Bing Zhaofcca8d52013-03-04 16:27:53 -0800103 * Kernel needs to suspend all functions separately. Therefore all
104 * registered functions must have drivers with suspend and resume
105 * methods. Failing that the kernel simply removes the whole card.
106 *
107 * If already not suspended, this function allocates and sends a host
108 * sleep activate request to the firmware and turns off the traffic.
109 */
Shuah Khan3266d732013-07-03 10:47:10 -0600110static int mwifiex_pcie_suspend(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800111{
112 struct mwifiex_adapter *adapter;
113 struct pcie_service_card *card;
114 int hs_actived;
Shuah Khan3266d732013-07-03 10:47:10 -0600115 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800116
117 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900118 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800119 if (!card || !card->adapter) {
120 pr_err("Card or adapter structure is not valid\n");
121 return 0;
122 }
123 } else {
124 pr_err("PCIE device is not specified\n");
125 return 0;
126 }
127
128 adapter = card->adapter;
129
130 hs_actived = mwifiex_enable_hs(adapter);
131
132 /* Indicate device suspended */
133 adapter->is_suspended = true;
Amitkumar Karwarc0dbba62014-03-25 19:01:20 -0700134 adapter->hs_enabling = false;
Bing Zhaofcca8d52013-03-04 16:27:53 -0800135
136 return 0;
137}
138
139/*
140 * Kernel needs to suspend all functions separately. Therefore all
141 * registered functions must have drivers with suspend and resume
142 * methods. Failing that the kernel simply removes the whole card.
143 *
144 * If already not resumed, this function turns on the traffic and
145 * sends a host sleep cancel request to the firmware.
146 */
Shuah Khan3266d732013-07-03 10:47:10 -0600147static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800148{
149 struct mwifiex_adapter *adapter;
150 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600151 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800152
153 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900154 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800155 if (!card || !card->adapter) {
156 pr_err("Card or adapter structure is not valid\n");
157 return 0;
158 }
159 } else {
160 pr_err("PCIE device is not specified\n");
161 return 0;
162 }
163
164 adapter = card->adapter;
165
166 if (!adapter->is_suspended) {
167 dev_warn(adapter->dev, "Device already resumed\n");
168 return 0;
169 }
170
171 adapter->is_suspended = false;
172
173 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
174 MWIFIEX_ASYNC_CMD);
175
176 return 0;
177}
Bing Zhao8509e822013-03-04 16:27:54 -0800178#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800179
180/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700181 * This function probes an mwifiex device and registers it. It allocates
182 * the card structure, enables PCIE function number and initiates the
183 * device registration and initialization procedure by adding a logical
184 * interface.
185 */
186static int mwifiex_pcie_probe(struct pci_dev *pdev,
187 const struct pci_device_id *ent)
188{
189 struct pcie_service_card *card;
190
191 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700192 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700193
194 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000195 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700196 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700197
198 card->dev = pdev;
199
Avinash Patildd04e6a2013-02-08 18:18:06 -0800200 if (ent->driver_data) {
201 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
202 card->pcie.firmware = data->firmware;
203 card->pcie.reg = data->reg;
204 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
Amitkumar Karwar828cf222014-02-27 19:35:13 -0800205 card->pcie.tx_buf_size = data->tx_buf_size;
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700206 card->pcie.supports_fw_dump = data->supports_fw_dump;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800207 }
208
Amitkumar Karward930fae2011-10-11 17:41:21 -0700209 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
210 MWIFIEX_PCIE)) {
211 pr_err("%s failed\n", __func__);
212 kfree(card);
213 return -1;
214 }
215
216 return 0;
217}
218
219/*
220 * This function removes the interface and frees up the card structure.
221 */
222static void mwifiex_pcie_remove(struct pci_dev *pdev)
223{
224 struct pcie_service_card *card;
225 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700226 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700227
228 card = pci_get_drvdata(pdev);
229 if (!card)
230 return;
231
232 adapter = card->adapter;
233 if (!adapter || !adapter->priv_num)
234 return;
235
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700236 cancel_work_sync(&adapter->iface_work);
237
Amitkumar Karward930fae2011-10-11 17:41:21 -0700238 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600239#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700240 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600241 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700242#endif
243
Amitkumar Karwar848819f2014-02-27 19:35:17 -0800244 mwifiex_deauthenticate_all(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700245
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700246 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700247
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700248 mwifiex_disable_auto_ds(priv);
249
250 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700251 }
252
253 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700254}
255
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700256static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
257{
258 user_rmmod = 1;
259 mwifiex_pcie_remove(pdev);
260
261 return;
262}
263
Benoit Taine9baa3c32014-08-08 15:56:03 +0200264static const struct pci_device_id mwifiex_ids[] = {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700265 {
266 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
267 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800268 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700269 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800270 {
271 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
272 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
273 .driver_data = (unsigned long) &mwifiex_pcie8897,
274 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700275 {},
276};
277
278MODULE_DEVICE_TABLE(pci, mwifiex_ids);
279
Shuah Khan3266d732013-07-03 10:47:10 -0600280#ifdef CONFIG_PM_SLEEP
281/* Power Management Hooks */
282static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
283 mwifiex_pcie_resume);
284#endif
285
Amitkumar Karward930fae2011-10-11 17:41:21 -0700286/* PCI Device Driver */
287static struct pci_driver __refdata mwifiex_pcie = {
288 .name = "mwifiex_pcie",
289 .id_table = mwifiex_ids,
290 .probe = mwifiex_pcie_probe,
291 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600292#ifdef CONFIG_PM_SLEEP
293 .driver = {
294 .pm = &mwifiex_pcie_pm_ops,
295 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700296#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700297 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700298};
299
300/*
301 * This function writes data into PCIE card register.
302 */
303static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
304{
305 struct pcie_service_card *card = adapter->card;
306
307 iowrite32(data, card->pci_mmap1 + reg);
308
309 return 0;
310}
311
312/*
313 * This function reads data from PCIE card register.
314 */
315static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
316{
317 struct pcie_service_card *card = adapter->card;
318
319 *data = ioread32(card->pci_mmap1 + reg);
320
321 return 0;
322}
323
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700324/* This function reads u8 data from PCIE card register. */
325static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
326 int reg, u8 *data)
327{
328 struct pcie_service_card *card = adapter->card;
329
330 *data = ioread8(card->pci_mmap1 + reg);
331
332 return 0;
333}
334
Amitkumar Karward930fae2011-10-11 17:41:21 -0700335/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700336 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700337 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700338static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700339{
340 int i = 0;
341
Avinash Patilc0880a22013-03-22 21:49:07 -0700342 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700343 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700344 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700345 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800346 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700347 break;
348 }
349
Avinash Patilc0880a22013-03-22 21:49:07 -0700350 return;
351}
352
Avinash Patilc4bc9802014-03-18 22:19:17 -0700353static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
354 u32 max_delay_loop_cnt)
355{
356 struct pcie_service_card *card = adapter->card;
357 u8 *buffer;
358 u32 sleep_cookie, count;
359
360 for (count = 0; count < max_delay_loop_cnt; count++) {
361 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
362 sleep_cookie = *(u32 *)buffer;
363
364 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
365 dev_dbg(adapter->dev,
366 "sleep cookie found at count %d\n", count);
367 break;
368 }
369 usleep_range(20, 30);
370 }
371
372 if (count >= max_delay_loop_cnt)
373 dev_dbg(adapter->dev,
374 "max count reached while accessing sleep cookie\n");
375}
376
Avinash Patilc0880a22013-03-22 21:49:07 -0700377/* This function wakes up the card by reading fw_status register. */
378static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
379{
380 u32 fw_status;
381 struct pcie_service_card *card = adapter->card;
382 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
383
Amitkumar Karward930fae2011-10-11 17:41:21 -0700384 dev_dbg(adapter->dev, "event: Wakeup device...\n");
385
Avinash Patilc0880a22013-03-22 21:49:07 -0700386 if (reg->sleep_cookie)
387 mwifiex_pcie_dev_wakeup_delay(adapter);
388
389 /* Reading fw_status register will wakeup device */
390 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
391 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700392 return -1;
393 }
394
Avinash Patilc0880a22013-03-22 21:49:07 -0700395 if (reg->sleep_cookie) {
396 mwifiex_pcie_dev_wakeup_delay(adapter);
397 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
398 adapter->ps_state = PS_STATE_AWAKE;
399 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700400
401 return 0;
402}
403
404/*
405 * This function is called after the card has woken up.
406 *
407 * The card configuration register is reset.
408 */
409static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
410{
411 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
412
413 return 0;
414}
415
416/*
417 * This function disables the host interrupt.
418 *
419 * The host interrupt mask is read, the disable bit is reset and
420 * written back to the card host interrupt mask register.
421 */
422static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
423{
424 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
425 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
426 0x00000000)) {
427 dev_warn(adapter->dev, "Disable host interrupt failed\n");
428 return -1;
429 }
430 }
431
432 return 0;
433}
434
435/*
436 * This function enables the host interrupt.
437 *
438 * The host interrupt enable mask is written to the card
439 * host interrupt mask register.
440 */
441static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
442{
443 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
444 /* Simply write the mask to the register */
445 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
446 HOST_INTR_MASK)) {
447 dev_warn(adapter->dev, "Enable host interrupt failed\n");
448 return -1;
449 }
450 }
451
452 return 0;
453}
454
455/*
Avinash Patil07324842013-02-08 18:18:07 -0800456 * This function initializes TX buffer ring descriptors
457 */
458static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
459{
460 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800461 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800462 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800463 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800464 int i;
465
466 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
467 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800468 if (reg->pfu_enabled) {
469 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
470 (sizeof(*desc2) * i);
471 desc2 = card->txbd_ring[i];
472 memset(desc2, 0, sizeof(*desc2));
473 } else {
474 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
475 (sizeof(*desc) * i);
476 desc = card->txbd_ring[i];
477 memset(desc, 0, sizeof(*desc));
478 }
Avinash Patil07324842013-02-08 18:18:07 -0800479 }
480
481 return 0;
482}
483
484/* This function initializes RX buffer ring descriptors. Each SKB is allocated
485 * here and after mapping PCI memory, its physical address is assigned to
486 * PCIE Rx buffer descriptor's physical address.
487 */
488static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
489{
490 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800491 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800492 struct sk_buff *skb;
493 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800494 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800495 dma_addr_t buf_pa;
496 int i;
497
498 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
499 /* Allocate skb here so that firmware can DMA data from it */
500 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
501 if (!skb) {
502 dev_err(adapter->dev,
503 "Unable to allocate skb for RX ring.\n");
504 kfree(card->rxbd_ring_vbase);
505 return -ENOMEM;
506 }
507
508 if (mwifiex_map_pci_memory(adapter, skb,
509 MWIFIEX_RX_DATA_BUF_SIZE,
510 PCI_DMA_FROMDEVICE))
511 return -1;
512
Aaron Durbindbccc922014-02-07 16:25:50 -0800513 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800514
515 dev_dbg(adapter->dev,
516 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
517 skb, skb->len, skb->data, (u32)buf_pa,
518 (u32)((u64)buf_pa >> 32));
519
520 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800521 if (reg->pfu_enabled) {
522 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
523 (sizeof(*desc2) * i);
524 desc2 = card->rxbd_ring[i];
525 desc2->paddr = buf_pa;
526 desc2->len = (u16)skb->len;
527 desc2->frag_len = (u16)skb->len;
528 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
529 desc2->offset = 0;
530 } else {
531 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
532 (sizeof(*desc) * i));
533 desc = card->rxbd_ring[i];
534 desc->paddr = buf_pa;
535 desc->len = (u16)skb->len;
536 desc->flags = 0;
537 }
Avinash Patil07324842013-02-08 18:18:07 -0800538 }
539
540 return 0;
541}
542
543/* This function initializes event buffer ring descriptors. Each SKB is
544 * allocated here and after mapping PCI memory, its physical address is assigned
545 * to PCIE Rx buffer descriptor's physical address
546 */
547static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
548{
549 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800550 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800551 struct sk_buff *skb;
552 dma_addr_t buf_pa;
553 int i;
554
555 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
556 /* Allocate skb here so that firmware can DMA data from it */
557 skb = dev_alloc_skb(MAX_EVENT_SIZE);
558 if (!skb) {
559 dev_err(adapter->dev,
560 "Unable to allocate skb for EVENT buf.\n");
561 kfree(card->evtbd_ring_vbase);
562 return -ENOMEM;
563 }
564 skb_put(skb, MAX_EVENT_SIZE);
565
566 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
567 PCI_DMA_FROMDEVICE))
568 return -1;
569
Aaron Durbindbccc922014-02-07 16:25:50 -0800570 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800571
572 dev_dbg(adapter->dev,
573 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
574 skb, skb->len, skb->data, (u32)buf_pa,
575 (u32)((u64)buf_pa >> 32));
576
577 card->evt_buf_list[i] = skb;
578 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
579 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800580 desc = card->evtbd_ring[i];
581 desc->paddr = buf_pa;
582 desc->len = (u16)skb->len;
583 desc->flags = 0;
584 }
585
586 return 0;
587}
588
589/* This function cleans up TX buffer rings. If any of the buffer list has valid
590 * SKB address, associated SKB is freed.
591 */
592static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
593{
594 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800595 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800596 struct sk_buff *skb;
597 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800598 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800599 int i;
600
601 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800602 if (reg->pfu_enabled) {
603 desc2 = card->txbd_ring[i];
604 if (card->tx_buf_list[i]) {
605 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800606 mwifiex_unmap_pci_memory(adapter, skb,
607 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800608 dev_kfree_skb_any(skb);
609 }
610 memset(desc2, 0, sizeof(*desc2));
611 } else {
612 desc = card->txbd_ring[i];
613 if (card->tx_buf_list[i]) {
614 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800615 mwifiex_unmap_pci_memory(adapter, skb,
616 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800617 dev_kfree_skb_any(skb);
618 }
619 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800620 }
621 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800622 }
623
624 return;
625}
626
627/* This function cleans up RX buffer rings. If any of the buffer list has valid
628 * SKB address, associated SKB is freed.
629 */
630static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
631{
632 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800633 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800634 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800635 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800636 struct sk_buff *skb;
637 int i;
638
639 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800640 if (reg->pfu_enabled) {
641 desc2 = card->rxbd_ring[i];
642 if (card->rx_buf_list[i]) {
643 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800644 mwifiex_unmap_pci_memory(adapter, skb,
645 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800646 dev_kfree_skb_any(skb);
647 }
648 memset(desc2, 0, sizeof(*desc2));
649 } else {
650 desc = card->rxbd_ring[i];
651 if (card->rx_buf_list[i]) {
652 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800653 mwifiex_unmap_pci_memory(adapter, skb,
654 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800655 dev_kfree_skb_any(skb);
656 }
657 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800658 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800659 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800660 }
661
662 return;
663}
664
665/* This function cleans up event buffer rings. If any of the buffer list has
666 * valid SKB address, associated SKB is freed.
667 */
668static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
669{
670 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800671 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800672 struct sk_buff *skb;
673 int i;
674
675 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
676 desc = card->evtbd_ring[i];
677 if (card->evt_buf_list[i]) {
678 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800679 mwifiex_unmap_pci_memory(adapter, skb,
680 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800681 dev_kfree_skb_any(skb);
682 }
683 card->evt_buf_list[i] = NULL;
684 memset(desc, 0, sizeof(*desc));
685 }
686
687 return;
688}
689
690/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700691 */
692static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
693{
694 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800695 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700696
697 /*
698 * driver maintaines the write pointer and firmware maintaines the read
699 * pointer. The write pointer starts at 0 (zero) while the read pointer
700 * starts at zero with rollover bit set
701 */
702 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800703
704 if (reg->pfu_enabled)
705 card->txbd_rdptr = 0;
706 else
707 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700708
709 /* allocate shared memory for the BD ring and divide the same in to
710 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800711 if (reg->pfu_enabled)
712 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
713 MWIFIEX_MAX_TXRX_BD;
714 else
715 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
716 MWIFIEX_MAX_TXRX_BD;
717
Amitkumar Karward930fae2011-10-11 17:41:21 -0700718 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700719 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800720 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
721 card->txbd_ring_size,
722 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700723 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800724 dev_err(adapter->dev,
725 "allocate consistent memory (%d bytes) failed!\n",
726 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800727 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700728 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700729 dev_dbg(adapter->dev,
730 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800731 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700732 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700733
Avinash Patil07324842013-02-08 18:18:07 -0800734 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700735}
736
737static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
738{
739 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800740 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700741
Avinash Patil07324842013-02-08 18:18:07 -0800742 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700743
Avinash Patilfc331462013-01-03 21:21:30 -0800744 if (card->txbd_ring_vbase)
745 pci_free_consistent(card->dev, card->txbd_ring_size,
746 card->txbd_ring_vbase,
747 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700748 card->txbd_ring_size = 0;
749 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800750 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700751 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800752 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700753
754 return 0;
755}
756
757/*
758 * This function creates buffer descriptor ring for RX
759 */
760static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
761{
762 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800763 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700764
765 /*
766 * driver maintaines the read pointer and firmware maintaines the write
767 * pointer. The write pointer starts at 0 (zero) while the read pointer
768 * starts at zero with rollover bit set
769 */
770 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800771 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700772
Avinash Patilca8f2112013-02-08 18:18:09 -0800773 if (reg->pfu_enabled)
774 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
775 MWIFIEX_MAX_TXRX_BD;
776 else
777 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
778 MWIFIEX_MAX_TXRX_BD;
779
Amitkumar Karward930fae2011-10-11 17:41:21 -0700780 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700781 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800782 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
783 card->rxbd_ring_size,
784 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700785 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800786 dev_err(adapter->dev,
787 "allocate consistent memory (%d bytes) failed!\n",
788 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800789 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700790 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700791
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700792 dev_dbg(adapter->dev,
793 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
794 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
795 (u32)((u64)card->rxbd_ring_pbase >> 32),
796 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700797
Avinash Patil07324842013-02-08 18:18:07 -0800798 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700799}
800
801/*
802 * This function deletes Buffer descriptor ring for RX
803 */
804static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
805{
806 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800807 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700808
Avinash Patil07324842013-02-08 18:18:07 -0800809 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700810
Avinash Patilfc331462013-01-03 21:21:30 -0800811 if (card->rxbd_ring_vbase)
812 pci_free_consistent(card->dev, card->rxbd_ring_size,
813 card->rxbd_ring_vbase,
814 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700815 card->rxbd_ring_size = 0;
816 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800817 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700818 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800819 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700820
821 return 0;
822}
823
824/*
825 * This function creates buffer descriptor ring for Events
826 */
827static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
828{
829 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800830 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700831
832 /*
833 * driver maintaines the read pointer and firmware maintaines the write
834 * pointer. The write pointer starts at 0 (zero) while the read pointer
835 * starts at zero with rollover bit set
836 */
837 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800838 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700839
Avinash Patile05dc3e2013-02-08 18:18:08 -0800840 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800841 MWIFIEX_MAX_EVT_BD;
842
Amitkumar Karward930fae2011-10-11 17:41:21 -0700843 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700844 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800845 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
846 card->evtbd_ring_size,
847 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700848 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700849 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800850 "allocate consistent memory (%d bytes) failed!\n",
851 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800852 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700853 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700854
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700855 dev_dbg(adapter->dev,
856 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
857 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
858 (u32)((u64)card->evtbd_ring_pbase >> 32),
859 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700860
Avinash Patil07324842013-02-08 18:18:07 -0800861 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700862}
863
864/*
865 * This function deletes Buffer descriptor ring for Events
866 */
867static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
868{
869 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800870 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700871
Avinash Patil07324842013-02-08 18:18:07 -0800872 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700873
Avinash Patilfc331462013-01-03 21:21:30 -0800874 if (card->evtbd_ring_vbase)
875 pci_free_consistent(card->dev, card->evtbd_ring_size,
876 card->evtbd_ring_vbase,
877 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700878 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800879 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700880 card->evtbd_ring_size = 0;
881 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800882 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700883
884 return 0;
885}
886
887/*
888 * This function allocates a buffer for CMDRSP
889 */
890static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
891{
892 struct pcie_service_card *card = adapter->card;
893 struct sk_buff *skb;
894
895 /* Allocate memory for receiving command response data */
896 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
897 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700898 dev_err(adapter->dev,
899 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700900 return -ENOMEM;
901 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700902 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800903 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
904 PCI_DMA_FROMDEVICE))
905 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700906
Avinash Patilfc331462013-01-03 21:21:30 -0800907 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700908
909 return 0;
910}
911
912/*
913 * This function deletes a buffer for CMDRSP
914 */
915static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
916{
917 struct pcie_service_card *card;
918
919 if (!adapter)
920 return 0;
921
922 card = adapter->card;
923
Avinash Patilfc331462013-01-03 21:21:30 -0800924 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800925 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
926 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700927 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800928 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700929
Avinash Patilfc331462013-01-03 21:21:30 -0800930 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800931 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
932 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800933 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700934 return 0;
935}
936
937/*
938 * This function allocates a buffer for sleep cookie
939 */
940static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
941{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700942 struct pcie_service_card *card = adapter->card;
943
Avinash Patilfc331462013-01-03 21:21:30 -0800944 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
945 &card->sleep_cookie_pbase);
946 if (!card->sleep_cookie_vbase) {
947 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700948 return -ENOMEM;
949 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700950 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800951 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700952
953 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800954 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700955
956 return 0;
957}
958
959/*
960 * This function deletes buffer for sleep cookie
961 */
962static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
963{
964 struct pcie_service_card *card;
965
966 if (!adapter)
967 return 0;
968
969 card = adapter->card;
970
Avinash Patilfc331462013-01-03 21:21:30 -0800971 if (card && card->sleep_cookie_vbase) {
972 pci_free_consistent(card->dev, sizeof(u32),
973 card->sleep_cookie_vbase,
974 card->sleep_cookie_pbase);
975 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700976 }
977
978 return 0;
979}
980
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800981/* This function flushes the TX buffer descriptor ring
982 * This function defined as handler is also called while cleaning TXRX
983 * during disconnect/ bss stop.
984 */
985static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
986{
987 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800988
Avinash Patil48f4d912013-02-20 21:12:58 -0800989 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800990 card->txbd_flush = 1;
991 /* write pointer already set at last send
992 * send dnld-rdy intr again, wait for completion.
993 */
994 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
995 CPU_INTR_DNLD_RDY)) {
996 dev_err(adapter->dev,
997 "failed to assert dnld-rdy interrupt.\n");
998 return -1;
999 }
1000 }
1001 return 0;
1002}
1003
Amitkumar Karward930fae2011-10-11 17:41:21 -07001004/*
Avinash Patile7f767a2013-01-03 21:21:32 -08001005 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -07001006 */
Avinash Patile7f767a2013-01-03 21:21:32 -08001007static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001008{
Avinash Patile7f767a2013-01-03 21:21:32 -08001009 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -08001010 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001011 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001012 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001013 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001014 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001015
1016 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1017 mwifiex_pm_wakeup_card(adapter);
1018
1019 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001020 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001021 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001022 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001023 return -1;
1024 }
1025
Avinash Patile7f767a2013-01-03 21:21:32 -08001026 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
1027 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001028
Avinash Patilca8f2112013-02-08 18:18:09 -08001029 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001030 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001031 while (((card->txbd_rdptr & reg->tx_mask) !=
1032 (rdptr & reg->tx_mask)) ||
1033 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
1034 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -08001035 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
1036 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001037
1038 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -08001039
Avinash Patile7f767a2013-01-03 21:21:32 -08001040 if (skb) {
1041 dev_dbg(adapter->dev,
1042 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
1043 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -08001044 mwifiex_unmap_pci_memory(adapter, skb,
1045 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001046
1047 unmap_count++;
1048
1049 if (card->txbd_flush)
1050 mwifiex_write_data_complete(adapter, skb, 0,
1051 -1);
1052 else
1053 mwifiex_write_data_complete(adapter, skb, 0, 0);
1054 }
1055
1056 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001057
1058 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001059 desc2 = card->txbd_ring[wrdoneidx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001060 memset(desc2, 0, sizeof(*desc2));
1061 } else {
1062 desc = card->txbd_ring[wrdoneidx];
1063 memset(desc, 0, sizeof(*desc));
1064 }
1065 switch (card->dev->device) {
1066 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1067 card->txbd_rdptr++;
1068 break;
1069 case PCIE_DEVICE_ID_MARVELL_88W8897:
1070 card->txbd_rdptr += reg->ring_tx_start_ptr;
1071 break;
1072 }
1073
Avinash Patile7f767a2013-01-03 21:21:32 -08001074
Avinash Patildd04e6a2013-02-08 18:18:06 -08001075 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001076 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001077 reg->tx_rollover_ind) ^
1078 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001079 }
1080
1081 if (unmap_count)
1082 adapter->data_sent = false;
1083
1084 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001085 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001086 card->txbd_flush = 0;
1087 else
1088 mwifiex_clean_pcie_ring_buf(adapter);
1089 }
1090
1091 return 0;
1092}
1093
1094/* This function sends data buffer to device. First 4 bytes of payload
1095 * are filled with payload length and payload type. Then this payload
1096 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1097 * Download ready interrupt to FW is deffered if Tx ring is not full and
1098 * additional payload can be accomodated.
Avinash Patil8d767dc2014-05-13 19:50:13 -07001099 * Caller must ensure tx_param parameter to this function is not NULL.
Avinash Patile7f767a2013-01-03 21:21:32 -08001100 */
1101static int
1102mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1103 struct mwifiex_tx_param *tx_param)
1104{
1105 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001106 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001107 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001108 int ret;
1109 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001110 struct mwifiex_pcie_buf_desc *desc = NULL;
1111 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001112 __le16 *tmp;
1113
1114 if (!(skb->data && skb->len)) {
1115 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1116 __func__, skb->data, skb->len);
1117 return -1;
1118 }
1119
1120 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1121 mwifiex_pm_wakeup_card(adapter);
1122
Avinash Patilca8f2112013-02-08 18:18:09 -08001123 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001124 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1125 card->txbd_rdptr, card->txbd_wrptr);
1126 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001127 u8 *payload;
1128
1129 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001130 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001131 tmp = (__le16 *)&payload[0];
1132 *tmp = cpu_to_le16((u16)skb->len);
1133 tmp = (__le16 *)&payload[2];
1134 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001135
Aaron Durbindbccc922014-02-07 16:25:50 -08001136 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001137 PCI_DMA_TODEVICE))
1138 return -1;
1139
Avinash Patilca8f2112013-02-08 18:18:09 -08001140 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001141 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001142 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001143
Avinash Patilca8f2112013-02-08 18:18:09 -08001144 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001145 desc2 = card->txbd_ring[wrindx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001146 desc2->paddr = buf_pa;
1147 desc2->len = (u16)skb->len;
1148 desc2->frag_len = (u16)skb->len;
1149 desc2->offset = 0;
1150 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1151 MWIFIEX_BD_FLAG_LAST_DESC;
1152 } else {
1153 desc = card->txbd_ring[wrindx];
1154 desc->paddr = buf_pa;
1155 desc->len = (u16)skb->len;
1156 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1157 MWIFIEX_BD_FLAG_LAST_DESC;
1158 }
1159
1160 switch (card->dev->device) {
1161 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1162 card->txbd_wrptr++;
1163 break;
1164 case PCIE_DEVICE_ID_MARVELL_88W8897:
1165 card->txbd_wrptr += reg->ring_tx_start_ptr;
1166 break;
1167 }
1168
1169 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001170 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001171 reg->tx_rollover_ind) ^
1172 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001173
Avinash Patilca8f2112013-02-08 18:18:09 -08001174 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001175 /* Write the TX ring write pointer in to reg->tx_wrptr */
1176 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001177 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001178 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001179 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001180 ret = -1;
1181 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001182 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001183 if ((mwifiex_pcie_txbd_not_full(card)) &&
1184 tx_param->next_pkt_len) {
1185 /* have more packets and TxBD still can hold more */
1186 dev_dbg(adapter->dev,
1187 "SEND DATA: delay dnld-rdy interrupt.\n");
1188 adapter->data_sent = false;
1189 } else {
1190 /* Send the TX ready interrupt */
1191 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1192 CPU_INTR_DNLD_RDY)) {
1193 dev_err(adapter->dev,
1194 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1195 ret = -1;
1196 goto done_unmap;
1197 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001198 }
1199 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001200 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001201 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001202 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001203 dev_dbg(adapter->dev,
1204 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001205 adapter->data_sent = true;
1206 /* Send the TX ready interrupt */
1207 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1208 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001209 dev_err(adapter->dev,
1210 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001211 return -EBUSY;
1212 }
1213
Avinash Patile7f767a2013-01-03 21:21:32 -08001214 return -EINPROGRESS;
1215done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001216 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001217 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001218 if (reg->pfu_enabled)
1219 memset(desc2, 0, sizeof(*desc2));
1220 else
1221 memset(desc, 0, sizeof(*desc));
1222
Avinash Patile7f767a2013-01-03 21:21:32 -08001223 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001224}
1225
1226/*
1227 * This function handles received buffer ring and
1228 * dispatches packets to upper
1229 */
1230static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1231{
1232 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001233 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001234 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001235 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001236 int ret = 0;
1237 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001238 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001239 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001240
Avinash Patile7f767a2013-01-03 21:21:32 -08001241 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1242 mwifiex_pm_wakeup_card(adapter);
1243
Amitkumar Karward930fae2011-10-11 17:41:21 -07001244 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001245 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001246 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001247 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001248 ret = -1;
1249 goto done;
1250 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001251 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001252
Avinash Patildd04e6a2013-02-08 18:18:06 -08001253 while (((wrptr & reg->rx_mask) !=
1254 (card->rxbd_rdptr & reg->rx_mask)) ||
1255 ((wrptr & reg->rx_rollover_ind) ==
1256 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001257 struct sk_buff *skb_data;
1258 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001259 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001260
Avinash Patildd04e6a2013-02-08 18:18:06 -08001261 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001262 skb_data = card->rx_buf_list[rd_index];
1263
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001264 /* If skb allocation was failed earlier for Rx packet,
1265 * rx_buf_list[rd_index] would have been left with a NULL.
1266 */
1267 if (!skb_data)
1268 return -ENOMEM;
1269
Aaron Durbindbccc922014-02-07 16:25:50 -08001270 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001271 card->rx_buf_list[rd_index] = NULL;
1272
Amitkumar Karward930fae2011-10-11 17:41:21 -07001273 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001274 * first 2 bytes for len, next 2 bytes is for type
1275 */
1276 pkt_len = *((__le16 *)skb_data->data);
1277 rx_len = le16_to_cpu(pkt_len);
Avinash Patil42a028a2014-09-12 20:08:47 +05301278 if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
1279 rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
1280 dev_err(adapter->dev,
1281 "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
1282 rx_len, card->rxbd_rdptr, wrptr);
1283 dev_kfree_skb_any(skb_data);
1284 } else {
1285 skb_put(skb_data, rx_len);
1286 dev_dbg(adapter->dev,
1287 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1288 card->rxbd_rdptr, wrptr, rx_len);
1289 skb_pull(skb_data, INTF_HEADER_LEN);
Avinash Patil6e251172014-09-12 20:08:59 +05301290 if (adapter->rx_work_enabled) {
Avinash Patil6e251172014-09-12 20:08:59 +05301291 skb_queue_tail(&adapter->rx_data_q, skb_data);
Avinash Patil6e251172014-09-12 20:08:59 +05301292 adapter->data_received = true;
1293 atomic_inc(&adapter->rx_pending);
1294 } else {
1295 mwifiex_handle_rx_packet(adapter, skb_data);
1296 }
Avinash Patil42a028a2014-09-12 20:08:47 +05301297 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001298
1299 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001300 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001301 dev_err(adapter->dev,
1302 "Unable to allocate skb.\n");
1303 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001304 }
1305
Avinash Patile7f767a2013-01-03 21:21:32 -08001306 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1307 MWIFIEX_RX_DATA_BUF_SIZE,
1308 PCI_DMA_FROMDEVICE))
1309 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001310
Aaron Durbindbccc922014-02-07 16:25:50 -08001311 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001312
1313 dev_dbg(adapter->dev,
1314 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1315 skb_tmp, rd_index);
1316 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001317
1318 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001319 desc2 = card->rxbd_ring[rd_index];
Avinash Patilca8f2112013-02-08 18:18:09 -08001320 desc2->paddr = buf_pa;
1321 desc2->len = skb_tmp->len;
1322 desc2->frag_len = skb_tmp->len;
1323 desc2->offset = 0;
1324 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1325 } else {
1326 desc = card->rxbd_ring[rd_index];
1327 desc->paddr = buf_pa;
1328 desc->len = skb_tmp->len;
1329 desc->flags = 0;
1330 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001331
Avinash Patildd04e6a2013-02-08 18:18:06 -08001332 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001333 MWIFIEX_MAX_TXRX_BD) {
1334 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001335 reg->rx_rollover_ind) ^
1336 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001337 }
1338 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001339 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001340
Avinash Patilca8f2112013-02-08 18:18:09 -08001341 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001342 /* Write the RX ring read pointer in to reg->rx_rdptr */
1343 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001344 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001345 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001346 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001347 ret = -1;
1348 goto done;
1349 }
1350
1351 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001352 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001353 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001354 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001355 ret = -1;
1356 goto done;
1357 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001358 dev_dbg(adapter->dev,
1359 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001360 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001361 }
1362
1363done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001364 return ret;
1365}
1366
1367/*
1368 * This function downloads the boot command to device
1369 */
1370static int
1371mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1372{
Avinash Patilfc331462013-01-03 21:21:30 -08001373 dma_addr_t buf_pa;
1374 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001375 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001376
Avinash Patilfc331462013-01-03 21:21:30 -08001377 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001378 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001379 "Invalid parameter in %s <%p. len %d>\n",
1380 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001381 return -1;
1382 }
1383
Avinash Patilfc331462013-01-03 21:21:30 -08001384 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1385 return -1;
1386
Aaron Durbindbccc922014-02-07 16:25:50 -08001387 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001388
Avinash Patildd04e6a2013-02-08 18:18:06 -08001389 /* Write the lower 32bits of the physical address to low command
1390 * address scratch register
1391 */
1392 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001393 dev_err(adapter->dev,
1394 "%s: failed to write download command to boot code.\n",
1395 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001396 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001397 return -1;
1398 }
1399
Avinash Patildd04e6a2013-02-08 18:18:06 -08001400 /* Write the upper 32bits of the physical address to high command
1401 * address scratch register
1402 */
1403 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001404 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001405 dev_err(adapter->dev,
1406 "%s: failed to write download command to boot code.\n",
1407 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001408 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001409 return -1;
1410 }
1411
Avinash Patildd04e6a2013-02-08 18:18:06 -08001412 /* Write the command length to cmd_size scratch register */
1413 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001414 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001415 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001416 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001417 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001418 return -1;
1419 }
1420
1421 /* Ring the door bell */
1422 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1423 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001424 dev_err(adapter->dev,
1425 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001426 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001427 return -1;
1428 }
1429
1430 return 0;
1431}
1432
Avinash Patilc6d1d872013-01-03 21:21:29 -08001433/* This function init rx port in firmware which in turn enables to receive data
1434 * from device before transmitting any packet.
1435 */
1436static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1437{
1438 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001439 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001440 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001441
Avinash Patildd04e6a2013-02-08 18:18:06 -08001442 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001443 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1444 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001445 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001446 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001447 return -1;
1448 }
1449 return 0;
1450}
1451
1452/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001453 */
1454static int
1455mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1456{
1457 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001458 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001459 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001460 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1461 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001462
1463 if (!(skb->data && skb->len)) {
1464 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001465 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001466 return -1;
1467 }
1468
1469 /* Make sure a command response buffer is available */
1470 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001471 dev_err(adapter->dev,
1472 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001473 return -EBUSY;
1474 }
1475
Avinash Patilfc331462013-01-03 21:21:30 -08001476 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1477 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001478
1479 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001480
1481 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1482 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1483
1484 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1485 return -1;
1486
1487 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001488
1489 /* To send a command, the driver will:
1490 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001491 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001492 2. Ring the door bell (i.e. set the door bell interrupt)
1493
1494 In response to door bell interrupt, the firmware will perform
1495 the DMA of the command packet (first header to obtain the total
1496 length and then rest of the command).
1497 */
1498
1499 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001500 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001501 /* Write the lower 32bits of the cmdrsp buffer physical
1502 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001503 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001504 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001505 dev_err(adapter->dev,
1506 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001507 ret = -1;
1508 goto done;
1509 }
1510 /* Write the upper 32bits of the cmdrsp buffer physical
1511 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001512 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001513 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001514 dev_err(adapter->dev,
1515 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001516 ret = -1;
1517 goto done;
1518 }
1519 }
1520
Aaron Durbindbccc922014-02-07 16:25:50 -08001521 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001522 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1523 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1524 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001525 dev_err(adapter->dev,
1526 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001527 ret = -1;
1528 goto done;
1529 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001530 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1531 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001532 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001533 dev_err(adapter->dev,
1534 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001535 ret = -1;
1536 goto done;
1537 }
1538
Avinash Patildd04e6a2013-02-08 18:18:06 -08001539 /* Write the command length to reg->cmd_size */
1540 if (mwifiex_write_reg(adapter, reg->cmd_size,
1541 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001542 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001543 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001544 ret = -1;
1545 goto done;
1546 }
1547
1548 /* Ring the door bell */
1549 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1550 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001551 dev_err(adapter->dev,
1552 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001553 ret = -1;
1554 goto done;
1555 }
1556
1557done:
1558 if (ret)
1559 adapter->cmd_sent = false;
1560
1561 return 0;
1562}
1563
1564/*
1565 * This function handles command complete interrupt
1566 */
1567static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1568{
1569 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001570 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001571 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001572 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001573 u16 rx_len;
1574 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001575
1576 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1577
Aaron Durbindbccc922014-02-07 16:25:50 -08001578 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001579
Aaron Durbin189b3292014-02-07 16:25:51 -08001580 /* Unmap the command as a response has been received. */
1581 if (card->cmd_buf) {
1582 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1583 PCI_DMA_TODEVICE);
1584 card->cmd_buf = NULL;
1585 }
1586
Avinash Patilfc331462013-01-03 21:21:30 -08001587 pkt_len = *((__le16 *)skb->data);
1588 rx_len = le16_to_cpu(pkt_len);
1589 skb_trim(skb, rx_len);
1590 skb_pull(skb, INTF_HEADER_LEN);
1591
Amitkumar Karward930fae2011-10-11 17:41:21 -07001592 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001593 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001594 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1595 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001596 mwifiex_pcie_enable_host_int(adapter);
1597 if (mwifiex_write_reg(adapter,
1598 PCIE_CPU_INT_EVENT,
1599 CPU_INTR_SLEEP_CFM_DONE)) {
1600 dev_warn(adapter->dev,
1601 "Write register failed\n");
1602 return -1;
1603 }
Avinash Patilc4bc9802014-03-18 22:19:17 -07001604 mwifiex_delay_for_sleep_cookie(adapter,
1605 MWIFIEX_MAX_DELAY_COUNT);
Avinash Patil52301a82013-02-12 14:38:32 -08001606 while (reg->sleep_cookie && (count++ < 10) &&
1607 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001608 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001609 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001610 dev_err(adapter->dev,
1611 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001612 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001613 memcpy(adapter->upld_buf, skb->data,
1614 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001615 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001616 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1617 PCI_DMA_FROMDEVICE))
1618 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001619 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001620 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001621 adapter->cmd_resp_received = true;
1622 /* Take the pointer and set it to CMD node and will
1623 return in the response complete callback */
1624 card->cmdrsp_buf = NULL;
1625
1626 /* Clear the cmd-rsp buffer address in scratch registers. This
1627 will prevent firmware from writing to the same response
1628 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001629 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001630 dev_err(adapter->dev,
1631 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001632 return -1;
1633 }
1634 /* Write the upper 32bits of the cmdrsp buffer physical
1635 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001636 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001637 dev_err(adapter->dev,
1638 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001639 return -1;
1640 }
1641 }
1642
1643 return 0;
1644}
1645
1646/*
1647 * Command Response processing complete handler
1648 */
1649static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1650 struct sk_buff *skb)
1651{
1652 struct pcie_service_card *card = adapter->card;
1653
1654 if (skb) {
1655 card->cmdrsp_buf = skb;
1656 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001657 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1658 PCI_DMA_FROMDEVICE))
1659 return -1;
1660 }
1661
Amitkumar Karward930fae2011-10-11 17:41:21 -07001662 return 0;
1663}
1664
1665/*
1666 * This function handles firmware event ready interrupt
1667 */
1668static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1669{
1670 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001671 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001672 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1673 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001674 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001675
1676 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1677 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001678
1679 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001680 dev_dbg(adapter->dev, "info: Event being processed, "
1681 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001682 return 0;
1683 }
1684
1685 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1686 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1687 return -1;
1688 }
1689
1690 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001691 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001692 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001693 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001694 return -1;
1695 }
1696
1697 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001698 card->evtbd_rdptr, wrptr);
1699 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1700 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001701 ((wrptr & reg->evt_rollover_ind) ==
1702 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001703 struct sk_buff *skb_cmd;
1704 __le16 data_len = 0;
1705 u16 evt_len;
1706
1707 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1708 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001709 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001710
Amitkumar Karward930fae2011-10-11 17:41:21 -07001711 /* Take the pointer and set it to event pointer in adapter
1712 and will return back after event handling callback */
1713 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001714 desc = card->evtbd_ring[rdptr];
1715 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001716
1717 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1718 adapter->event_cause = event;
1719 /* The first 4bytes will be the event transfer header
1720 len is 2 bytes followed by type which is 2 bytes */
1721 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1722 evt_len = le16_to_cpu(data_len);
1723
1724 skb_pull(skb_cmd, INTF_HEADER_LEN);
1725 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1726
1727 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1728 memcpy(adapter->event_body, skb_cmd->data +
1729 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1730 MWIFIEX_EVENT_HEADER_LEN);
1731
1732 adapter->event_received = true;
1733 adapter->event_skb = skb_cmd;
1734
1735 /* Do not update the event read pointer here, wait till the
1736 buffer is released. This is just to make things simpler,
1737 we need to find a better method of managing these buffers.
1738 */
Avinash Patil2703a662014-09-12 20:08:49 +05301739 } else {
1740 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1741 CPU_INTR_EVENT_DONE)) {
1742 dev_warn(adapter->dev,
1743 "Write register failed\n");
1744 return -1;
1745 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001746 }
1747
1748 return 0;
1749}
1750
1751/*
1752 * Event processing complete handler
1753 */
1754static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1755 struct sk_buff *skb)
1756{
1757 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001758 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001759 int ret = 0;
1760 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1761 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001762 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001763
1764 if (!skb)
1765 return 0;
1766
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001767 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001768 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001769 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001770 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001771 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001772
1773 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001774 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001775 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001776 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001777 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001778 }
1779
1780 if (!card->evt_buf_list[rdptr]) {
1781 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001782 if (mwifiex_map_pci_memory(adapter, skb,
1783 MAX_EVENT_SIZE,
1784 PCI_DMA_FROMDEVICE))
1785 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001786 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001787 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001788 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001789 desc->len = (u16)skb->len;
1790 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001791 skb = NULL;
1792 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001793 dev_dbg(adapter->dev,
1794 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1795 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001796 }
1797
1798 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1799 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001800 reg->evt_rollover_ind) ^
1801 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001802 }
1803
1804 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001805 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001806
Avinash Patildd04e6a2013-02-08 18:18:06 -08001807 /* Write the event ring read pointer in to reg->evt_rdptr */
1808 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1809 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001810 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001811 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001812 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001813 }
1814
Amitkumar Karward930fae2011-10-11 17:41:21 -07001815 dev_dbg(adapter->dev, "info: Check Events Again\n");
1816 ret = mwifiex_pcie_process_event_ready(adapter);
1817
1818 return ret;
1819}
1820
1821/*
1822 * This function downloads the firmware to the card.
1823 *
1824 * Firmware is downloaded to the card in blocks. Every block download
1825 * is tested for CRC errors, and retried a number of times before
1826 * returning failure.
1827 */
1828static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1829 struct mwifiex_fw_image *fw)
1830{
1831 int ret;
1832 u8 *firmware = fw->fw_buf;
1833 u32 firmware_len = fw->fw_len;
1834 u32 offset = 0;
1835 struct sk_buff *skb;
1836 u32 txlen, tx_blocks = 0, tries, len;
1837 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001838 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001839 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001840
1841 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001842 dev_err(adapter->dev,
1843 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001844 return -1;
1845 }
1846
1847 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001848 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001849
1850 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001851 dev_err(adapter->dev,
1852 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001853 return -1;
1854 }
1855
1856 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1857 if (!skb) {
1858 ret = -ENOMEM;
1859 goto done;
1860 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001861
1862 /* Perform firmware data transfer */
1863 do {
1864 u32 ireg_intr = 0;
1865
1866 /* More data? */
1867 if (offset >= firmware_len)
1868 break;
1869
1870 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001871 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001872 &len);
1873 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001874 dev_warn(adapter->dev,
1875 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001876 goto done;
1877 }
1878 if (len)
1879 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001880 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001881 }
1882
1883 if (!len) {
1884 break;
1885 } else if (len > MWIFIEX_UPLD_SIZE) {
1886 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001887 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001888 ret = -1;
1889 goto done;
1890 }
1891
1892 txlen = len;
1893
1894 if (len & BIT(0)) {
1895 block_retry_cnt++;
1896 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1897 pr_err("FW download failure @ %d, over max "
1898 "retry count\n", offset);
1899 ret = -1;
1900 goto done;
1901 }
1902 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001903 "helper: len = 0x%04X, txlen = %d\n",
1904 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001905 len &= ~BIT(0);
1906 /* Setting this to 0 to resend from same offset */
1907 txlen = 0;
1908 } else {
1909 block_retry_cnt = 0;
1910 /* Set blocksize to transfer - checking for
1911 last block */
1912 if (firmware_len - offset < txlen)
1913 txlen = firmware_len - offset;
1914
1915 dev_dbg(adapter->dev, ".");
1916
Avinash Patildd04e6a2013-02-08 18:18:06 -08001917 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1918 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001919
1920 /* Copy payload to buffer */
1921 memmove(skb->data, &firmware[offset], txlen);
1922 }
1923
1924 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001925 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001926
1927 /* Send the boot command to device */
1928 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001929 dev_err(adapter->dev,
1930 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001931 ret = -1;
1932 goto done;
1933 }
Avinash Patilfc331462013-01-03 21:21:30 -08001934
Amitkumar Karward930fae2011-10-11 17:41:21 -07001935 /* Wait for the command done interrupt */
1936 do {
1937 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1938 &ireg_intr)) {
1939 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001940 "interrupt status during fw dnld.\n",
1941 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001942 mwifiex_unmap_pci_memory(adapter, skb,
1943 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001944 ret = -1;
1945 goto done;
1946 }
1947 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1948 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001949
Aaron Durbindbccc922014-02-07 16:25:50 -08001950 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001951
Amitkumar Karward930fae2011-10-11 17:41:21 -07001952 offset += txlen;
1953 } while (true);
1954
Amitkumar Karwarca5b20e2014-12-31 02:36:44 -08001955 dev_notice(adapter->dev,
1956 "info: FW download over, size %d bytes\n", offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001957
1958 ret = 0;
1959
1960done:
1961 dev_kfree_skb_any(skb);
1962 return ret;
1963}
1964
1965/*
1966 * This function checks the firmware status in card.
1967 *
1968 * The winner interface is also determined by this function.
1969 */
1970static int
1971mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1972{
1973 int ret = 0;
1974 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001975 struct pcie_service_card *card = adapter->card;
1976 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001977 u32 tries;
1978
1979 /* Mask spurios interrupts */
1980 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001981 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001982 dev_warn(adapter->dev, "Write register failed\n");
1983 return -1;
1984 }
1985
1986 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001987 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1988 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001989 dev_err(adapter->dev,
1990 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001991 return -1;
1992 }
1993
1994 /* Wait for firmware initialization event */
1995 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001996 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001997 &firmware_stat))
1998 ret = -1;
1999 else
2000 ret = 0;
2001 if (ret)
2002 continue;
2003 if (firmware_stat == FIRMWARE_READY_PCIE) {
2004 ret = 0;
2005 break;
2006 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07002007 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002008 ret = -1;
2009 }
2010 }
2011
2012 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08002013 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002014 &winner_status))
2015 ret = -1;
2016 else if (!winner_status) {
2017 dev_err(adapter->dev, "PCI-E is the winner\n");
2018 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002019 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002020 dev_err(adapter->dev,
2021 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
2022 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002023 }
2024 }
2025
2026 return ret;
2027}
2028
2029/*
2030 * This function reads the interrupt status from card.
2031 */
2032static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
2033{
2034 u32 pcie_ireg;
2035 unsigned long flags;
2036
2037 if (!mwifiex_pcie_ok_to_access_hw(adapter))
2038 return;
2039
2040 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
2041 dev_warn(adapter->dev, "Read register failed\n");
2042 return;
2043 }
2044
2045 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2046
2047 mwifiex_pcie_disable_host_int(adapter);
2048
2049 /* Clear the pending interrupts */
2050 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2051 ~pcie_ireg)) {
2052 dev_warn(adapter->dev, "Write register failed\n");
2053 return;
2054 }
2055 spin_lock_irqsave(&adapter->int_lock, flags);
2056 adapter->int_status |= pcie_ireg;
2057 spin_unlock_irqrestore(&adapter->int_lock, flags);
2058
Amitkumar Karwar1c975602014-02-18 15:41:56 -08002059 if (!adapter->pps_uapsd_mode &&
2060 adapter->ps_state == PS_STATE_SLEEP &&
2061 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002062 /* Potentially for PCIe we could get other
2063 * interrupts like shared. Don't change power
2064 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002065 adapter->ps_state = PS_STATE_AWAKE;
2066 adapter->pm_wakeup_fw_try = false;
Amitkumar Karwar46361872014-12-31 02:36:41 -08002067 del_timer(&adapter->wakeup_timer);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002068 }
2069 }
2070}
2071
2072/*
2073 * Interrupt handler for PCIe root port
2074 *
2075 * This function reads the interrupt status from firmware and assigns
2076 * the main process in workqueue which will handle the interrupt.
2077 */
2078static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2079{
2080 struct pci_dev *pdev = (struct pci_dev *)context;
2081 struct pcie_service_card *card;
2082 struct mwifiex_adapter *adapter;
2083
2084 if (!pdev) {
2085 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2086 goto exit;
2087 }
2088
Jingoo Hanb2a31202013-09-09 14:26:51 +09002089 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002090 if (!card || !card->adapter) {
2091 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002092 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002093 goto exit;
2094 }
2095 adapter = card->adapter;
2096
2097 if (adapter->surprise_removed)
2098 goto exit;
2099
2100 mwifiex_interrupt_status(adapter);
2101 queue_work(adapter->workqueue, &adapter->main_work);
2102
2103exit:
2104 return IRQ_HANDLED;
2105}
2106
2107/*
2108 * This function checks the current interrupt status.
2109 *
2110 * The following interrupts are checked and handled by this function -
2111 * - Data sent
2112 * - Command sent
2113 * - Command received
2114 * - Packets received
2115 * - Events received
2116 *
2117 * In case of Rx packets received, the packets are uploaded from card to
2118 * host and processed accordingly.
2119 */
2120static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2121{
2122 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002123 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002124 unsigned long flags;
2125
2126 spin_lock_irqsave(&adapter->int_lock, flags);
2127 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002128 pcie_ireg = adapter->int_status;
2129 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002130 spin_unlock_irqrestore(&adapter->int_lock, flags);
2131
Avinash Patil659c4782013-01-03 21:21:28 -08002132 while (pcie_ireg & HOST_INTR_MASK) {
2133 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2134 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002135 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2136 ret = mwifiex_pcie_send_data_complete(adapter);
2137 if (ret)
2138 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002139 }
Avinash Patil659c4782013-01-03 21:21:28 -08002140 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2141 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002142 dev_dbg(adapter->dev, "info: Rx DATA\n");
2143 ret = mwifiex_pcie_process_recv_data(adapter);
2144 if (ret)
2145 return ret;
2146 }
Avinash Patil659c4782013-01-03 21:21:28 -08002147 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2148 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002149 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2150 ret = mwifiex_pcie_process_event_ready(adapter);
2151 if (ret)
2152 return ret;
2153 }
2154
Avinash Patil659c4782013-01-03 21:21:28 -08002155 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2156 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002157 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002158 dev_dbg(adapter->dev,
2159 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002160 adapter->cmd_sent = false;
2161 }
2162 /* Handle command response */
2163 ret = mwifiex_pcie_process_cmd_complete(adapter);
2164 if (ret)
2165 return ret;
2166 }
2167
2168 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2169 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2170 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002171 dev_warn(adapter->dev,
2172 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002173 return -1;
2174 }
2175
2176 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2177 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002178 PCIE_HOST_INT_STATUS,
2179 ~pcie_ireg)) {
2180 dev_warn(adapter->dev,
2181 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002182 return -1;
2183 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002184 }
2185
2186 }
2187 }
2188 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002189 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002190 if (adapter->ps_state != PS_STATE_SLEEP)
2191 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002192
2193 return 0;
2194}
2195
2196/*
2197 * This function downloads data from driver to card.
2198 *
2199 * Both commands and data packets are transferred to the card by this
2200 * function.
2201 *
2202 * This function adds the PCIE specific header to the front of the buffer
2203 * before transferring. The header contains the length of the packet and
2204 * the type. The firmware handles the packets based upon this set type.
2205 */
2206static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2207 struct sk_buff *skb,
2208 struct mwifiex_tx_param *tx_param)
2209{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002210 if (!skb) {
2211 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002212 return -1;
2213 }
2214
2215 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002216 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002217 else if (type == MWIFIEX_TYPE_CMD)
2218 return mwifiex_pcie_send_cmd(adapter, skb);
2219
2220 return 0;
2221}
2222
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002223/* This function read/write firmware */
2224static enum rdwr_status
2225mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2226{
2227 int ret, tries;
2228 u8 ctrl_data;
2229 struct pcie_service_card *card = adapter->card;
2230 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2231
2232 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
2233 if (ret) {
2234 dev_err(adapter->dev, "PCIE write err\n");
2235 return RDWR_STATUS_FAILURE;
2236 }
2237
2238 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2239 mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
2240 if (ctrl_data == FW_DUMP_DONE)
2241 return RDWR_STATUS_SUCCESS;
2242 if (doneflag && ctrl_data == doneflag)
2243 return RDWR_STATUS_DONE;
2244 if (ctrl_data != FW_DUMP_HOST_READY) {
2245 dev_info(adapter->dev,
2246 "The ctrl reg was changed, re-try again!\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002247 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2248 FW_DUMP_HOST_READY);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002249 if (ret) {
2250 dev_err(adapter->dev, "PCIE write err\n");
2251 return RDWR_STATUS_FAILURE;
2252 }
2253 }
2254 usleep_range(100, 200);
2255 }
2256
2257 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2258 return RDWR_STATUS_FAILURE;
2259}
2260
2261/* This function dump firmware memory to file */
2262static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2263{
2264 struct pcie_service_card *card = adapter->card;
2265 const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
2266 unsigned int reg, reg_start, reg_end;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002267 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2268 enum rdwr_status stat;
2269 u32 memory_size;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002270 int ret;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002271 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2272
2273 if (!card->pcie.supports_fw_dump)
2274 return;
2275
2276 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2277 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2278
2279 if (entry->mem_ptr) {
2280 vfree(entry->mem_ptr);
2281 entry->mem_ptr = NULL;
2282 }
2283 entry->mem_size = 0;
2284 }
2285
Bing Zhao1d9e9542014-07-17 15:55:09 -07002286 dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002287
2288 /* Read the number of the memories which will dump */
2289 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2290 if (stat == RDWR_STATUS_FAILURE)
2291 goto done;
2292
2293 reg = creg->fw_dump_start;
2294 mwifiex_read_reg_byte(adapter, reg, &dump_num);
2295
2296 /* Read the length of every memory which will dump */
2297 for (idx = 0; idx < dump_num; idx++) {
2298 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2299
2300 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2301 if (stat == RDWR_STATUS_FAILURE)
2302 goto done;
2303
2304 memory_size = 0;
2305 reg = creg->fw_dump_start;
2306 for (i = 0; i < 4; i++) {
2307 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2308 memory_size |= (read_reg << (i * 8));
2309 reg++;
2310 }
2311
2312 if (memory_size == 0) {
2313 dev_info(adapter->dev, "Firmware dump Finished!\n");
Amitkumar Karwar7e174832014-09-18 07:18:50 -04002314 ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
2315 FW_DUMP_READ_DONE);
2316 if (ret) {
2317 dev_err(adapter->dev, "PCIE write err\n");
2318 goto done;
2319 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002320 break;
2321 }
2322
2323 dev_info(adapter->dev,
2324 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2325 entry->mem_ptr = vmalloc(memory_size + 1);
2326 entry->mem_size = memory_size;
2327 if (!entry->mem_ptr) {
2328 dev_err(adapter->dev,
2329 "Vmalloc %s failed\n", entry->mem_name);
2330 goto done;
2331 }
2332 dbg_ptr = entry->mem_ptr;
2333 end_ptr = dbg_ptr + memory_size;
2334
2335 doneflag = entry->done_flag;
Bing Zhao1d9e9542014-07-17 15:55:09 -07002336 dev_info(adapter->dev, "Start %s output, please wait...\n",
2337 entry->mem_name);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002338
2339 do {
2340 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2341 if (RDWR_STATUS_FAILURE == stat)
2342 goto done;
2343
2344 reg_start = creg->fw_dump_start;
2345 reg_end = creg->fw_dump_end;
2346 for (reg = reg_start; reg <= reg_end; reg++) {
2347 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
Amitkumar Karwar24716872014-09-18 08:04:01 -04002348 if (dbg_ptr < end_ptr) {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002349 dbg_ptr++;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002350 } else {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002351 dev_err(adapter->dev,
2352 "Allocated buf not enough\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002353 goto done;
2354 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002355 }
2356
2357 if (stat != RDWR_STATUS_DONE)
2358 continue;
2359
2360 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2361 entry->mem_name, dbg_ptr - entry->mem_ptr);
2362 break;
2363 } while (true);
2364 }
Bing Zhao1d9e9542014-07-17 15:55:09 -07002365 dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002366
2367 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2368
2369done:
2370 adapter->curr_mem_idx = 0;
2371}
2372
2373static void mwifiex_pcie_work(struct work_struct *work)
2374{
2375 struct mwifiex_adapter *adapter =
2376 container_of(work, struct mwifiex_adapter, iface_work);
2377
2378 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2379 &adapter->iface_work_flags))
2380 mwifiex_pcie_fw_dump_work(adapter);
2381}
2382
2383/* This function dumps FW information */
2384static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2385{
2386 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
2387 return;
2388
2389 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
2390
2391 schedule_work(&adapter->iface_work);
2392}
2393
Amitkumar Karward930fae2011-10-11 17:41:21 -07002394/*
2395 * This function initializes the PCI-E host memory space, WCB rings, etc.
2396 *
2397 * The following initializations steps are followed -
2398 * - Allocate TXBD ring buffers
2399 * - Allocate RXBD ring buffers
2400 * - Allocate event BD ring buffers
2401 * - Allocate command response ring buffer
2402 * - Allocate sleep cookie buffer
2403 */
2404static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2405{
2406 struct pcie_service_card *card = adapter->card;
2407 int ret;
2408 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002409 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002410
2411 pci_set_drvdata(pdev, card);
2412
2413 ret = pci_enable_device(pdev);
2414 if (ret)
2415 goto err_enable_dev;
2416
2417 pci_set_master(pdev);
2418
2419 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2420 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2421 if (ret) {
2422 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2423 goto err_set_dma_mask;
2424 }
2425
2426 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2427 if (ret) {
2428 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2429 goto err_set_dma_mask;
2430 }
2431
2432 ret = pci_request_region(pdev, 0, DRV_NAME);
2433 if (ret) {
2434 dev_err(adapter->dev, "req_reg(0) error\n");
2435 goto err_req_region0;
2436 }
2437 card->pci_mmap = pci_iomap(pdev, 0, 0);
2438 if (!card->pci_mmap) {
2439 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002440 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002441 goto err_iomap0;
2442 }
2443 ret = pci_request_region(pdev, 2, DRV_NAME);
2444 if (ret) {
2445 dev_err(adapter->dev, "req_reg(2) error\n");
2446 goto err_req_region2;
2447 }
2448 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2449 if (!card->pci_mmap1) {
2450 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002451 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002452 goto err_iomap2;
2453 }
2454
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002455 dev_dbg(adapter->dev,
2456 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2457 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002458
2459 card->cmdrsp_buf = NULL;
2460 ret = mwifiex_pcie_create_txbd_ring(adapter);
2461 if (ret)
2462 goto err_cre_txbd;
2463 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2464 if (ret)
2465 goto err_cre_rxbd;
2466 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2467 if (ret)
2468 goto err_cre_evtbd;
2469 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2470 if (ret)
2471 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002472 if (reg->sleep_cookie) {
2473 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2474 if (ret)
2475 goto err_alloc_cookie;
2476 } else {
2477 card->sleep_cookie_vbase = NULL;
2478 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002479 return ret;
2480
2481err_alloc_cookie:
2482 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2483err_alloc_cmdbuf:
2484 mwifiex_pcie_delete_evtbd_ring(adapter);
2485err_cre_evtbd:
2486 mwifiex_pcie_delete_rxbd_ring(adapter);
2487err_cre_rxbd:
2488 mwifiex_pcie_delete_txbd_ring(adapter);
2489err_cre_txbd:
2490 pci_iounmap(pdev, card->pci_mmap1);
2491err_iomap2:
2492 pci_release_region(pdev, 2);
2493err_req_region2:
2494 pci_iounmap(pdev, card->pci_mmap);
2495err_iomap0:
2496 pci_release_region(pdev, 0);
2497err_req_region0:
2498err_set_dma_mask:
2499 pci_disable_device(pdev);
2500err_enable_dev:
2501 pci_set_drvdata(pdev, NULL);
2502 return ret;
2503}
2504
2505/*
2506 * This function cleans up the allocated card buffers.
2507 *
2508 * The following are freed by this function -
2509 * - TXBD ring buffers
2510 * - RXBD ring buffers
2511 * - Event BD ring buffers
2512 * - Command response ring buffer
2513 * - Sleep cookie buffer
2514 */
2515static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2516{
2517 struct pcie_service_card *card = adapter->card;
2518 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002519 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002520
Amitkumar Karward930fae2011-10-11 17:41:21 -07002521 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002522 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002523 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002524 dev_err(adapter->dev,
2525 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002526 }
2527
2528 if (pdev) {
2529 pci_iounmap(pdev, card->pci_mmap);
2530 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002531 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002532 pci_release_region(pdev, 2);
2533 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002534 pci_set_drvdata(pdev, NULL);
2535 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002536 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002537}
2538
2539/*
2540 * This function registers the PCIE device.
2541 *
2542 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2543 */
2544static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2545{
2546 int ret;
2547 struct pcie_service_card *card = adapter->card;
2548 struct pci_dev *pdev = card->dev;
2549
2550 /* save adapter pointer in card */
2551 card->adapter = adapter;
2552
2553 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2554 "MRVL_PCIE", pdev);
2555 if (ret) {
2556 pr_err("request_irq failed: ret=%d\n", ret);
2557 adapter->card = NULL;
2558 return -1;
2559 }
2560
2561 adapter->dev = &pdev->dev;
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002562 adapter->tx_buf_size = card->pcie.tx_buf_size;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002563 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
2564 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
Avinash Patildd04e6a2013-02-08 18:18:06 -08002565 strcpy(adapter->fw_name, card->pcie.firmware);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002566
2567 return 0;
2568}
2569
2570/*
2571 * This function unregisters the PCIE device.
2572 *
2573 * The PCIE IRQ is released, the function is disabled and driver
2574 * data is set to null.
2575 */
2576static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2577{
2578 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002579 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002580
2581 if (card) {
2582 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2583 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002584
Avinash Patil52301a82013-02-12 14:38:32 -08002585 reg = card->pcie.reg;
2586 if (reg->sleep_cookie)
2587 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2588
Avinash Patilfc331462013-01-03 21:21:30 -08002589 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2590 mwifiex_pcie_delete_evtbd_ring(adapter);
2591 mwifiex_pcie_delete_rxbd_ring(adapter);
2592 mwifiex_pcie_delete_txbd_ring(adapter);
2593 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002594 }
2595}
2596
2597static struct mwifiex_if_ops pcie_ops = {
2598 .init_if = mwifiex_pcie_init,
2599 .cleanup_if = mwifiex_pcie_cleanup,
2600 .check_fw_status = mwifiex_check_fw_status,
2601 .prog_fw = mwifiex_prog_fw_w_helper,
2602 .register_dev = mwifiex_register_dev,
2603 .unregister_dev = mwifiex_unregister_dev,
2604 .enable_int = mwifiex_pcie_enable_host_int,
2605 .process_int_status = mwifiex_process_int_status,
2606 .host_to_card = mwifiex_pcie_host_to_card,
2607 .wakeup = mwifiex_pm_wakeup_card,
2608 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2609
2610 /* PCIE specific */
2611 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2612 .event_complete = mwifiex_pcie_event_complete,
2613 .update_mp_end_port = NULL,
2614 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002615 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002616 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002617 .fw_dump = mwifiex_pcie_fw_dump,
2618 .iface_work = mwifiex_pcie_work,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002619};
2620
2621/*
2622 * This function initializes the PCIE driver module.
2623 *
2624 * This initiates the semaphore and registers the device with
2625 * PCIE bus.
2626 */
2627static int mwifiex_pcie_init_module(void)
2628{
2629 int ret;
2630
Avinash Patilca8f2112013-02-08 18:18:09 -08002631 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002632
2633 sema_init(&add_remove_card_sem, 1);
2634
2635 /* Clear the flag in case user removes the card. */
2636 user_rmmod = 0;
2637
2638 ret = pci_register_driver(&mwifiex_pcie);
2639 if (ret)
2640 pr_err("Driver register failed!\n");
2641 else
2642 pr_debug("info: Driver registered successfully!\n");
2643
2644 return ret;
2645}
2646
2647/*
2648 * This function cleans up the PCIE driver.
2649 *
2650 * The following major steps are followed for cleanup -
2651 * - Resume the device if its suspended
2652 * - Disconnect the device if connected
2653 * - Shutdown the firmware
2654 * - Unregister the device from PCIE bus.
2655 */
2656static void mwifiex_pcie_cleanup_module(void)
2657{
2658 if (!down_interruptible(&add_remove_card_sem))
2659 up(&add_remove_card_sem);
2660
2661 /* Set the flag as user is removing this module. */
2662 user_rmmod = 1;
2663
2664 pci_unregister_driver(&mwifiex_pcie);
2665}
2666
2667module_init(mwifiex_pcie_init_module);
2668module_exit(mwifiex_pcie_cleanup_module);
2669
2670MODULE_AUTHOR("Marvell International Ltd.");
2671MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2672MODULE_VERSION(PCIE_VERSION);
2673MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002674MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2675MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);