blob: 88bda3f68164a9892d58ce158d68e51c2462fe6c [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;
Avinash Patilb4e8aeb2015-02-11 23:12:26 +0530206 card->pcie.can_dump_fw = data->can_dump_fw;
Avinash Patil1fe192d2015-01-23 17:09:19 +0530207 card->pcie.can_ext_scan = data->can_ext_scan;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800208 }
209
Amitkumar Karward930fae2011-10-11 17:41:21 -0700210 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
211 MWIFIEX_PCIE)) {
212 pr_err("%s failed\n", __func__);
213 kfree(card);
214 return -1;
215 }
216
217 return 0;
218}
219
220/*
221 * This function removes the interface and frees up the card structure.
222 */
223static void mwifiex_pcie_remove(struct pci_dev *pdev)
224{
225 struct pcie_service_card *card;
226 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700227 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700228
229 card = pci_get_drvdata(pdev);
230 if (!card)
231 return;
232
233 adapter = card->adapter;
234 if (!adapter || !adapter->priv_num)
235 return;
236
237 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600238#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700239 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600240 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700241#endif
242
Amitkumar Karwar848819f2014-02-27 19:35:17 -0800243 mwifiex_deauthenticate_all(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700244
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700245 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700246
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700247 mwifiex_disable_auto_ds(priv);
248
249 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700250 }
251
252 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700253}
254
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700255static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
256{
257 user_rmmod = 1;
258 mwifiex_pcie_remove(pdev);
259
260 return;
261}
262
Benoit Taine9baa3c32014-08-08 15:56:03 +0200263static const struct pci_device_id mwifiex_ids[] = {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700264 {
265 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
266 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800267 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700268 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800269 {
270 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
271 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
272 .driver_data = (unsigned long) &mwifiex_pcie8897,
273 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700274 {},
275};
276
277MODULE_DEVICE_TABLE(pci, mwifiex_ids);
278
Shuah Khan3266d732013-07-03 10:47:10 -0600279#ifdef CONFIG_PM_SLEEP
280/* Power Management Hooks */
281static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
282 mwifiex_pcie_resume);
283#endif
284
Amitkumar Karward930fae2011-10-11 17:41:21 -0700285/* PCI Device Driver */
286static struct pci_driver __refdata mwifiex_pcie = {
287 .name = "mwifiex_pcie",
288 .id_table = mwifiex_ids,
289 .probe = mwifiex_pcie_probe,
290 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600291#ifdef CONFIG_PM_SLEEP
292 .driver = {
293 .pm = &mwifiex_pcie_pm_ops,
294 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700295#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700296 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700297};
298
299/*
300 * This function writes data into PCIE card register.
301 */
302static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
303{
304 struct pcie_service_card *card = adapter->card;
305
306 iowrite32(data, card->pci_mmap1 + reg);
307
308 return 0;
309}
310
311/*
312 * This function reads data from PCIE card register.
313 */
314static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
315{
316 struct pcie_service_card *card = adapter->card;
317
318 *data = ioread32(card->pci_mmap1 + reg);
319
320 return 0;
321}
322
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700323/* This function reads u8 data from PCIE card register. */
324static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
325 int reg, u8 *data)
326{
327 struct pcie_service_card *card = adapter->card;
328
329 *data = ioread8(card->pci_mmap1 + reg);
330
331 return 0;
332}
333
Amitkumar Karward930fae2011-10-11 17:41:21 -0700334/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700335 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700336 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700337static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700338{
339 int i = 0;
340
Avinash Patilc0880a22013-03-22 21:49:07 -0700341 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700342 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700343 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700344 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800345 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700346 break;
347 }
348
Avinash Patilc0880a22013-03-22 21:49:07 -0700349 return;
350}
351
Avinash Patilc4bc9802014-03-18 22:19:17 -0700352static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
353 u32 max_delay_loop_cnt)
354{
355 struct pcie_service_card *card = adapter->card;
356 u8 *buffer;
357 u32 sleep_cookie, count;
358
359 for (count = 0; count < max_delay_loop_cnt; count++) {
360 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
361 sleep_cookie = *(u32 *)buffer;
362
363 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
364 dev_dbg(adapter->dev,
365 "sleep cookie found at count %d\n", count);
366 break;
367 }
368 usleep_range(20, 30);
369 }
370
371 if (count >= max_delay_loop_cnt)
372 dev_dbg(adapter->dev,
373 "max count reached while accessing sleep cookie\n");
374}
375
Avinash Patilc0880a22013-03-22 21:49:07 -0700376/* This function wakes up the card by reading fw_status register. */
377static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
378{
379 u32 fw_status;
380 struct pcie_service_card *card = adapter->card;
381 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
382
Amitkumar Karward930fae2011-10-11 17:41:21 -0700383 dev_dbg(adapter->dev, "event: Wakeup device...\n");
384
Avinash Patilc0880a22013-03-22 21:49:07 -0700385 if (reg->sleep_cookie)
386 mwifiex_pcie_dev_wakeup_delay(adapter);
387
388 /* Reading fw_status register will wakeup device */
389 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
390 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700391 return -1;
392 }
393
Avinash Patilc0880a22013-03-22 21:49:07 -0700394 if (reg->sleep_cookie) {
395 mwifiex_pcie_dev_wakeup_delay(adapter);
396 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
397 adapter->ps_state = PS_STATE_AWAKE;
398 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700399
400 return 0;
401}
402
403/*
404 * This function is called after the card has woken up.
405 *
406 * The card configuration register is reset.
407 */
408static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
409{
410 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
411
412 return 0;
413}
414
415/*
416 * This function disables the host interrupt.
417 *
418 * The host interrupt mask is read, the disable bit is reset and
419 * written back to the card host interrupt mask register.
420 */
421static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
422{
423 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
424 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
425 0x00000000)) {
426 dev_warn(adapter->dev, "Disable host interrupt failed\n");
427 return -1;
428 }
429 }
430
431 return 0;
432}
433
434/*
435 * This function enables the host interrupt.
436 *
437 * The host interrupt enable mask is written to the card
438 * host interrupt mask register.
439 */
440static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
441{
442 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
443 /* Simply write the mask to the register */
444 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
445 HOST_INTR_MASK)) {
446 dev_warn(adapter->dev, "Enable host interrupt failed\n");
447 return -1;
448 }
449 }
450
451 return 0;
452}
453
454/*
Avinash Patil07324842013-02-08 18:18:07 -0800455 * This function initializes TX buffer ring descriptors
456 */
457static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
458{
459 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800460 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800461 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800462 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800463 int i;
464
465 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
466 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800467 if (reg->pfu_enabled) {
468 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
469 (sizeof(*desc2) * i);
470 desc2 = card->txbd_ring[i];
471 memset(desc2, 0, sizeof(*desc2));
472 } else {
473 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
474 (sizeof(*desc) * i);
475 desc = card->txbd_ring[i];
476 memset(desc, 0, sizeof(*desc));
477 }
Avinash Patil07324842013-02-08 18:18:07 -0800478 }
479
480 return 0;
481}
482
483/* This function initializes RX buffer ring descriptors. Each SKB is allocated
484 * here and after mapping PCI memory, its physical address is assigned to
485 * PCIE Rx buffer descriptor's physical address.
486 */
487static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
488{
489 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800490 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800491 struct sk_buff *skb;
492 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800493 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800494 dma_addr_t buf_pa;
495 int i;
496
497 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
498 /* Allocate skb here so that firmware can DMA data from it */
Avinash Patil62159942015-03-13 17:37:52 +0530499 skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
500 GFP_KERNEL | GFP_DMA);
Avinash Patil07324842013-02-08 18:18:07 -0800501 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
Avinash Patil62159942015-03-13 17:37:52 +05301299 skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1300 GFP_KERNEL | GFP_DMA);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001301 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001302 dev_err(adapter->dev,
1303 "Unable to allocate skb.\n");
1304 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001305 }
1306
Avinash Patile7f767a2013-01-03 21:21:32 -08001307 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1308 MWIFIEX_RX_DATA_BUF_SIZE,
1309 PCI_DMA_FROMDEVICE))
1310 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001311
Aaron Durbindbccc922014-02-07 16:25:50 -08001312 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001313
1314 dev_dbg(adapter->dev,
1315 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1316 skb_tmp, rd_index);
1317 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001318
1319 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001320 desc2 = card->rxbd_ring[rd_index];
Avinash Patilca8f2112013-02-08 18:18:09 -08001321 desc2->paddr = buf_pa;
1322 desc2->len = skb_tmp->len;
1323 desc2->frag_len = skb_tmp->len;
1324 desc2->offset = 0;
1325 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1326 } else {
1327 desc = card->rxbd_ring[rd_index];
1328 desc->paddr = buf_pa;
1329 desc->len = skb_tmp->len;
1330 desc->flags = 0;
1331 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001332
Avinash Patildd04e6a2013-02-08 18:18:06 -08001333 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001334 MWIFIEX_MAX_TXRX_BD) {
1335 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001336 reg->rx_rollover_ind) ^
1337 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001338 }
1339 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001340 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001341
Avinash Patilca8f2112013-02-08 18:18:09 -08001342 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001343 /* Write the RX ring read pointer in to reg->rx_rdptr */
1344 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001345 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001346 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001347 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001348 ret = -1;
1349 goto done;
1350 }
1351
1352 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001353 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001354 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001355 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001356 ret = -1;
1357 goto done;
1358 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001359 dev_dbg(adapter->dev,
1360 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001361 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001362 }
1363
1364done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001365 return ret;
1366}
1367
1368/*
1369 * This function downloads the boot command to device
1370 */
1371static int
1372mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1373{
Avinash Patilfc331462013-01-03 21:21:30 -08001374 dma_addr_t buf_pa;
1375 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001376 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001377
Avinash Patilfc331462013-01-03 21:21:30 -08001378 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001379 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001380 "Invalid parameter in %s <%p. len %d>\n",
1381 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001382 return -1;
1383 }
1384
Avinash Patilfc331462013-01-03 21:21:30 -08001385 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1386 return -1;
1387
Aaron Durbindbccc922014-02-07 16:25:50 -08001388 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001389
Avinash Patildd04e6a2013-02-08 18:18:06 -08001390 /* Write the lower 32bits of the physical address to low command
1391 * address scratch register
1392 */
1393 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001394 dev_err(adapter->dev,
1395 "%s: failed to write download command to boot code.\n",
1396 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001397 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001398 return -1;
1399 }
1400
Avinash Patildd04e6a2013-02-08 18:18:06 -08001401 /* Write the upper 32bits of the physical address to high command
1402 * address scratch register
1403 */
1404 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001405 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001406 dev_err(adapter->dev,
1407 "%s: failed to write download command to boot code.\n",
1408 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001409 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001410 return -1;
1411 }
1412
Avinash Patildd04e6a2013-02-08 18:18:06 -08001413 /* Write the command length to cmd_size scratch register */
1414 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001415 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001416 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001417 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001418 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001419 return -1;
1420 }
1421
1422 /* Ring the door bell */
1423 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1424 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001425 dev_err(adapter->dev,
1426 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001427 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001428 return -1;
1429 }
1430
1431 return 0;
1432}
1433
Avinash Patilc6d1d872013-01-03 21:21:29 -08001434/* This function init rx port in firmware which in turn enables to receive data
1435 * from device before transmitting any packet.
1436 */
1437static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1438{
1439 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001440 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001441 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001442
Avinash Patildd04e6a2013-02-08 18:18:06 -08001443 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001444 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1445 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001446 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001447 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001448 return -1;
1449 }
1450 return 0;
1451}
1452
1453/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001454 */
1455static int
1456mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1457{
1458 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001459 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001460 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001461 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1462 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001463
1464 if (!(skb->data && skb->len)) {
1465 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001466 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001467 return -1;
1468 }
1469
1470 /* Make sure a command response buffer is available */
1471 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001472 dev_err(adapter->dev,
1473 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001474 return -EBUSY;
1475 }
1476
Avinash Patilfc331462013-01-03 21:21:30 -08001477 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1478 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001479
1480 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001481
1482 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1483 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1484
1485 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1486 return -1;
1487
1488 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001489
1490 /* To send a command, the driver will:
1491 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001492 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001493 2. Ring the door bell (i.e. set the door bell interrupt)
1494
1495 In response to door bell interrupt, the firmware will perform
1496 the DMA of the command packet (first header to obtain the total
1497 length and then rest of the command).
1498 */
1499
1500 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001501 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001502 /* Write the lower 32bits of the cmdrsp buffer physical
1503 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001504 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001505 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001506 dev_err(adapter->dev,
1507 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001508 ret = -1;
1509 goto done;
1510 }
1511 /* Write the upper 32bits of the cmdrsp buffer physical
1512 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001513 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001514 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001515 dev_err(adapter->dev,
1516 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001517 ret = -1;
1518 goto done;
1519 }
1520 }
1521
Aaron Durbindbccc922014-02-07 16:25:50 -08001522 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001523 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1524 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1525 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001526 dev_err(adapter->dev,
1527 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001528 ret = -1;
1529 goto done;
1530 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001531 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1532 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001533 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001534 dev_err(adapter->dev,
1535 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001536 ret = -1;
1537 goto done;
1538 }
1539
Avinash Patildd04e6a2013-02-08 18:18:06 -08001540 /* Write the command length to reg->cmd_size */
1541 if (mwifiex_write_reg(adapter, reg->cmd_size,
1542 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001543 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001544 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001545 ret = -1;
1546 goto done;
1547 }
1548
1549 /* Ring the door bell */
1550 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1551 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001552 dev_err(adapter->dev,
1553 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001554 ret = -1;
1555 goto done;
1556 }
1557
1558done:
1559 if (ret)
1560 adapter->cmd_sent = false;
1561
1562 return 0;
1563}
1564
1565/*
1566 * This function handles command complete interrupt
1567 */
1568static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1569{
1570 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001571 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001572 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001573 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001574 u16 rx_len;
1575 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001576
1577 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1578
Aaron Durbindbccc922014-02-07 16:25:50 -08001579 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001580
Aaron Durbin189b3292014-02-07 16:25:51 -08001581 /* Unmap the command as a response has been received. */
1582 if (card->cmd_buf) {
1583 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1584 PCI_DMA_TODEVICE);
1585 card->cmd_buf = NULL;
1586 }
1587
Avinash Patilfc331462013-01-03 21:21:30 -08001588 pkt_len = *((__le16 *)skb->data);
1589 rx_len = le16_to_cpu(pkt_len);
1590 skb_trim(skb, rx_len);
1591 skb_pull(skb, INTF_HEADER_LEN);
1592
Amitkumar Karward930fae2011-10-11 17:41:21 -07001593 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001594 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001595 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1596 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001597 mwifiex_pcie_enable_host_int(adapter);
1598 if (mwifiex_write_reg(adapter,
1599 PCIE_CPU_INT_EVENT,
1600 CPU_INTR_SLEEP_CFM_DONE)) {
1601 dev_warn(adapter->dev,
1602 "Write register failed\n");
1603 return -1;
1604 }
Avinash Patilc4bc9802014-03-18 22:19:17 -07001605 mwifiex_delay_for_sleep_cookie(adapter,
1606 MWIFIEX_MAX_DELAY_COUNT);
Avinash Patil52301a82013-02-12 14:38:32 -08001607 while (reg->sleep_cookie && (count++ < 10) &&
1608 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001609 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001610 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001611 dev_err(adapter->dev,
1612 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001613 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001614 memcpy(adapter->upld_buf, skb->data,
1615 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001616 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001617 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1618 PCI_DMA_FROMDEVICE))
1619 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001620 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001621 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001622 adapter->cmd_resp_received = true;
1623 /* Take the pointer and set it to CMD node and will
1624 return in the response complete callback */
1625 card->cmdrsp_buf = NULL;
1626
1627 /* Clear the cmd-rsp buffer address in scratch registers. This
1628 will prevent firmware from writing to the same response
1629 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001630 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001631 dev_err(adapter->dev,
1632 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001633 return -1;
1634 }
1635 /* Write the upper 32bits of the cmdrsp buffer physical
1636 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001637 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001638 dev_err(adapter->dev,
1639 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001640 return -1;
1641 }
1642 }
1643
1644 return 0;
1645}
1646
1647/*
1648 * Command Response processing complete handler
1649 */
1650static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1651 struct sk_buff *skb)
1652{
1653 struct pcie_service_card *card = adapter->card;
1654
1655 if (skb) {
1656 card->cmdrsp_buf = skb;
1657 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001658 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1659 PCI_DMA_FROMDEVICE))
1660 return -1;
1661 }
1662
Amitkumar Karward930fae2011-10-11 17:41:21 -07001663 return 0;
1664}
1665
1666/*
1667 * This function handles firmware event ready interrupt
1668 */
1669static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1670{
1671 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001672 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001673 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1674 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001675 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001676
1677 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1678 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001679
1680 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001681 dev_dbg(adapter->dev, "info: Event being processed, "
1682 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001683 return 0;
1684 }
1685
1686 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1687 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1688 return -1;
1689 }
1690
1691 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001692 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001693 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001694 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001695 return -1;
1696 }
1697
1698 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001699 card->evtbd_rdptr, wrptr);
1700 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1701 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001702 ((wrptr & reg->evt_rollover_ind) ==
1703 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001704 struct sk_buff *skb_cmd;
1705 __le16 data_len = 0;
1706 u16 evt_len;
1707
1708 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1709 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001710 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001711
Amitkumar Karward930fae2011-10-11 17:41:21 -07001712 /* Take the pointer and set it to event pointer in adapter
1713 and will return back after event handling callback */
1714 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001715 desc = card->evtbd_ring[rdptr];
1716 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001717
1718 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1719 adapter->event_cause = event;
1720 /* The first 4bytes will be the event transfer header
1721 len is 2 bytes followed by type which is 2 bytes */
1722 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1723 evt_len = le16_to_cpu(data_len);
Zhaoyang Liu868093a2015-05-12 00:48:19 +05301724 skb_trim(skb_cmd, evt_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001725 skb_pull(skb_cmd, INTF_HEADER_LEN);
1726 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1727
1728 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1729 memcpy(adapter->event_body, skb_cmd->data +
1730 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1731 MWIFIEX_EVENT_HEADER_LEN);
1732
1733 adapter->event_received = true;
1734 adapter->event_skb = skb_cmd;
1735
1736 /* Do not update the event read pointer here, wait till the
1737 buffer is released. This is just to make things simpler,
1738 we need to find a better method of managing these buffers.
1739 */
Avinash Patil2703a662014-09-12 20:08:49 +05301740 } else {
1741 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1742 CPU_INTR_EVENT_DONE)) {
1743 dev_warn(adapter->dev,
1744 "Write register failed\n");
1745 return -1;
1746 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001747 }
1748
1749 return 0;
1750}
1751
1752/*
1753 * Event processing complete handler
1754 */
1755static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1756 struct sk_buff *skb)
1757{
1758 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001759 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001760 int ret = 0;
1761 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1762 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001763 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001764
1765 if (!skb)
1766 return 0;
1767
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001768 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001769 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001770 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001771 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001772 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001773
1774 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001775 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001776 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001777 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001778 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001779 }
1780
1781 if (!card->evt_buf_list[rdptr]) {
1782 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001783 if (mwifiex_map_pci_memory(adapter, skb,
1784 MAX_EVENT_SIZE,
1785 PCI_DMA_FROMDEVICE))
1786 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001787 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001788 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001789 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001790 desc->len = (u16)skb->len;
1791 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001792 skb = NULL;
1793 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001794 dev_dbg(adapter->dev,
1795 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1796 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001797 }
1798
1799 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1800 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001801 reg->evt_rollover_ind) ^
1802 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001803 }
1804
1805 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001806 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001807
Avinash Patildd04e6a2013-02-08 18:18:06 -08001808 /* Write the event ring read pointer in to reg->evt_rdptr */
1809 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1810 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001811 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001812 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001813 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001814 }
1815
Amitkumar Karward930fae2011-10-11 17:41:21 -07001816 dev_dbg(adapter->dev, "info: Check Events Again\n");
1817 ret = mwifiex_pcie_process_event_ready(adapter);
1818
1819 return ret;
1820}
1821
1822/*
1823 * This function downloads the firmware to the card.
1824 *
1825 * Firmware is downloaded to the card in blocks. Every block download
1826 * is tested for CRC errors, and retried a number of times before
1827 * returning failure.
1828 */
1829static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1830 struct mwifiex_fw_image *fw)
1831{
1832 int ret;
1833 u8 *firmware = fw->fw_buf;
1834 u32 firmware_len = fw->fw_len;
1835 u32 offset = 0;
1836 struct sk_buff *skb;
1837 u32 txlen, tx_blocks = 0, tries, len;
1838 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001839 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001840 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001841
1842 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001843 dev_err(adapter->dev,
1844 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001845 return -1;
1846 }
1847
1848 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001849 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001850
1851 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001852 dev_err(adapter->dev,
1853 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001854 return -1;
1855 }
1856
1857 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1858 if (!skb) {
1859 ret = -ENOMEM;
1860 goto done;
1861 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001862
1863 /* Perform firmware data transfer */
1864 do {
1865 u32 ireg_intr = 0;
1866
1867 /* More data? */
1868 if (offset >= firmware_len)
1869 break;
1870
1871 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001872 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001873 &len);
1874 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001875 dev_warn(adapter->dev,
1876 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001877 goto done;
1878 }
1879 if (len)
1880 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001881 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001882 }
1883
1884 if (!len) {
1885 break;
1886 } else if (len > MWIFIEX_UPLD_SIZE) {
1887 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001888 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001889 ret = -1;
1890 goto done;
1891 }
1892
1893 txlen = len;
1894
1895 if (len & BIT(0)) {
1896 block_retry_cnt++;
1897 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1898 pr_err("FW download failure @ %d, over max "
1899 "retry count\n", offset);
1900 ret = -1;
1901 goto done;
1902 }
1903 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001904 "helper: len = 0x%04X, txlen = %d\n",
1905 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001906 len &= ~BIT(0);
1907 /* Setting this to 0 to resend from same offset */
1908 txlen = 0;
1909 } else {
1910 block_retry_cnt = 0;
1911 /* Set blocksize to transfer - checking for
1912 last block */
1913 if (firmware_len - offset < txlen)
1914 txlen = firmware_len - offset;
1915
1916 dev_dbg(adapter->dev, ".");
1917
Avinash Patildd04e6a2013-02-08 18:18:06 -08001918 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1919 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001920
1921 /* Copy payload to buffer */
1922 memmove(skb->data, &firmware[offset], txlen);
1923 }
1924
1925 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001926 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001927
1928 /* Send the boot command to device */
1929 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001930 dev_err(adapter->dev,
1931 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001932 ret = -1;
1933 goto done;
1934 }
Avinash Patilfc331462013-01-03 21:21:30 -08001935
Amitkumar Karward930fae2011-10-11 17:41:21 -07001936 /* Wait for the command done interrupt */
1937 do {
1938 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1939 &ireg_intr)) {
1940 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001941 "interrupt status during fw dnld.\n",
1942 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001943 mwifiex_unmap_pci_memory(adapter, skb,
1944 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001945 ret = -1;
1946 goto done;
1947 }
1948 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1949 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001950
Aaron Durbindbccc922014-02-07 16:25:50 -08001951 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001952
Amitkumar Karward930fae2011-10-11 17:41:21 -07001953 offset += txlen;
1954 } while (true);
1955
Amitkumar Karwarca5b20e2014-12-31 02:36:44 -08001956 dev_notice(adapter->dev,
1957 "info: FW download over, size %d bytes\n", offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001958
1959 ret = 0;
1960
1961done:
1962 dev_kfree_skb_any(skb);
1963 return ret;
1964}
1965
1966/*
1967 * This function checks the firmware status in card.
1968 *
1969 * The winner interface is also determined by this function.
1970 */
1971static int
1972mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1973{
1974 int ret = 0;
1975 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001976 struct pcie_service_card *card = adapter->card;
1977 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001978 u32 tries;
1979
1980 /* Mask spurios interrupts */
1981 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001982 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001983 dev_warn(adapter->dev, "Write register failed\n");
1984 return -1;
1985 }
1986
1987 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001988 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1989 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001990 dev_err(adapter->dev,
1991 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001992 return -1;
1993 }
1994
1995 /* Wait for firmware initialization event */
1996 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001997 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001998 &firmware_stat))
1999 ret = -1;
2000 else
2001 ret = 0;
2002 if (ret)
2003 continue;
2004 if (firmware_stat == FIRMWARE_READY_PCIE) {
2005 ret = 0;
2006 break;
2007 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07002008 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002009 ret = -1;
2010 }
2011 }
2012
2013 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08002014 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002015 &winner_status))
2016 ret = -1;
2017 else if (!winner_status) {
2018 dev_err(adapter->dev, "PCI-E is the winner\n");
2019 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002020 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002021 dev_err(adapter->dev,
2022 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
2023 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002024 }
2025 }
2026
2027 return ret;
2028}
2029
2030/*
2031 * This function reads the interrupt status from card.
2032 */
2033static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
2034{
2035 u32 pcie_ireg;
2036 unsigned long flags;
2037
2038 if (!mwifiex_pcie_ok_to_access_hw(adapter))
2039 return;
2040
2041 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
2042 dev_warn(adapter->dev, "Read register failed\n");
2043 return;
2044 }
2045
2046 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2047
2048 mwifiex_pcie_disable_host_int(adapter);
2049
2050 /* Clear the pending interrupts */
2051 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2052 ~pcie_ireg)) {
2053 dev_warn(adapter->dev, "Write register failed\n");
2054 return;
2055 }
2056 spin_lock_irqsave(&adapter->int_lock, flags);
2057 adapter->int_status |= pcie_ireg;
2058 spin_unlock_irqrestore(&adapter->int_lock, flags);
2059
Amitkumar Karwar1c975602014-02-18 15:41:56 -08002060 if (!adapter->pps_uapsd_mode &&
2061 adapter->ps_state == PS_STATE_SLEEP &&
2062 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002063 /* Potentially for PCIe we could get other
2064 * interrupts like shared. Don't change power
2065 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002066 adapter->ps_state = PS_STATE_AWAKE;
2067 adapter->pm_wakeup_fw_try = false;
Amitkumar Karwar46361872014-12-31 02:36:41 -08002068 del_timer(&adapter->wakeup_timer);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002069 }
2070 }
2071}
2072
2073/*
2074 * Interrupt handler for PCIe root port
2075 *
2076 * This function reads the interrupt status from firmware and assigns
2077 * the main process in workqueue which will handle the interrupt.
2078 */
2079static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2080{
2081 struct pci_dev *pdev = (struct pci_dev *)context;
2082 struct pcie_service_card *card;
2083 struct mwifiex_adapter *adapter;
2084
2085 if (!pdev) {
2086 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2087 goto exit;
2088 }
2089
Jingoo Hanb2a31202013-09-09 14:26:51 +09002090 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002091 if (!card || !card->adapter) {
2092 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002093 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002094 goto exit;
2095 }
2096 adapter = card->adapter;
2097
2098 if (adapter->surprise_removed)
2099 goto exit;
2100
2101 mwifiex_interrupt_status(adapter);
Shengzhen Lib2713f62015-03-13 17:37:54 +05302102 mwifiex_queue_main_work(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002103
2104exit:
2105 return IRQ_HANDLED;
2106}
2107
2108/*
2109 * This function checks the current interrupt status.
2110 *
2111 * The following interrupts are checked and handled by this function -
2112 * - Data sent
2113 * - Command sent
2114 * - Command received
2115 * - Packets received
2116 * - Events received
2117 *
2118 * In case of Rx packets received, the packets are uploaded from card to
2119 * host and processed accordingly.
2120 */
2121static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2122{
2123 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002124 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002125 unsigned long flags;
2126
2127 spin_lock_irqsave(&adapter->int_lock, flags);
2128 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002129 pcie_ireg = adapter->int_status;
2130 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002131 spin_unlock_irqrestore(&adapter->int_lock, flags);
2132
Avinash Patil659c4782013-01-03 21:21:28 -08002133 while (pcie_ireg & HOST_INTR_MASK) {
2134 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2135 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002136 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2137 ret = mwifiex_pcie_send_data_complete(adapter);
2138 if (ret)
2139 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002140 }
Avinash Patil659c4782013-01-03 21:21:28 -08002141 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2142 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002143 dev_dbg(adapter->dev, "info: Rx DATA\n");
2144 ret = mwifiex_pcie_process_recv_data(adapter);
2145 if (ret)
2146 return ret;
2147 }
Avinash Patil659c4782013-01-03 21:21:28 -08002148 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2149 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002150 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2151 ret = mwifiex_pcie_process_event_ready(adapter);
2152 if (ret)
2153 return ret;
2154 }
2155
Avinash Patil659c4782013-01-03 21:21:28 -08002156 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2157 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002158 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002159 dev_dbg(adapter->dev,
2160 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002161 adapter->cmd_sent = false;
2162 }
2163 /* Handle command response */
2164 ret = mwifiex_pcie_process_cmd_complete(adapter);
2165 if (ret)
2166 return ret;
2167 }
2168
2169 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2170 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2171 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002172 dev_warn(adapter->dev,
2173 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002174 return -1;
2175 }
2176
2177 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2178 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002179 PCIE_HOST_INT_STATUS,
2180 ~pcie_ireg)) {
2181 dev_warn(adapter->dev,
2182 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002183 return -1;
2184 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002185 }
2186
2187 }
2188 }
2189 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002190 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002191 if (adapter->ps_state != PS_STATE_SLEEP)
2192 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002193
2194 return 0;
2195}
2196
2197/*
2198 * This function downloads data from driver to card.
2199 *
2200 * Both commands and data packets are transferred to the card by this
2201 * function.
2202 *
2203 * This function adds the PCIE specific header to the front of the buffer
2204 * before transferring. The header contains the length of the packet and
2205 * the type. The firmware handles the packets based upon this set type.
2206 */
2207static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2208 struct sk_buff *skb,
2209 struct mwifiex_tx_param *tx_param)
2210{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002211 if (!skb) {
2212 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002213 return -1;
2214 }
2215
2216 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002217 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002218 else if (type == MWIFIEX_TYPE_CMD)
2219 return mwifiex_pcie_send_cmd(adapter, skb);
2220
2221 return 0;
2222}
2223
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002224/* This function read/write firmware */
2225static enum rdwr_status
2226mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2227{
2228 int ret, tries;
2229 u8 ctrl_data;
2230 struct pcie_service_card *card = adapter->card;
2231 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2232
2233 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
2234 if (ret) {
2235 dev_err(adapter->dev, "PCIE write err\n");
2236 return RDWR_STATUS_FAILURE;
2237 }
2238
2239 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2240 mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
2241 if (ctrl_data == FW_DUMP_DONE)
2242 return RDWR_STATUS_SUCCESS;
2243 if (doneflag && ctrl_data == doneflag)
2244 return RDWR_STATUS_DONE;
2245 if (ctrl_data != FW_DUMP_HOST_READY) {
2246 dev_info(adapter->dev,
2247 "The ctrl reg was changed, re-try again!\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002248 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2249 FW_DUMP_HOST_READY);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002250 if (ret) {
2251 dev_err(adapter->dev, "PCIE write err\n");
2252 return RDWR_STATUS_FAILURE;
2253 }
2254 }
2255 usleep_range(100, 200);
2256 }
2257
2258 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2259 return RDWR_STATUS_FAILURE;
2260}
2261
2262/* This function dump firmware memory to file */
2263static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2264{
2265 struct pcie_service_card *card = adapter->card;
2266 const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
2267 unsigned int reg, reg_start, reg_end;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002268 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2269 enum rdwr_status stat;
2270 u32 memory_size;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002271 int ret;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002272 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2273
Avinash Patilb4e8aeb2015-02-11 23:12:26 +05302274 if (!card->pcie.can_dump_fw)
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002275 return;
2276
2277 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2278 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2279
2280 if (entry->mem_ptr) {
2281 vfree(entry->mem_ptr);
2282 entry->mem_ptr = NULL;
2283 }
2284 entry->mem_size = 0;
2285 }
2286
Bing Zhao1d9e9542014-07-17 15:55:09 -07002287 dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002288
2289 /* Read the number of the memories which will dump */
2290 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2291 if (stat == RDWR_STATUS_FAILURE)
2292 goto done;
2293
2294 reg = creg->fw_dump_start;
2295 mwifiex_read_reg_byte(adapter, reg, &dump_num);
2296
2297 /* Read the length of every memory which will dump */
2298 for (idx = 0; idx < dump_num; idx++) {
2299 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2300
2301 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2302 if (stat == RDWR_STATUS_FAILURE)
2303 goto done;
2304
2305 memory_size = 0;
2306 reg = creg->fw_dump_start;
2307 for (i = 0; i < 4; i++) {
2308 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2309 memory_size |= (read_reg << (i * 8));
2310 reg++;
2311 }
2312
2313 if (memory_size == 0) {
2314 dev_info(adapter->dev, "Firmware dump Finished!\n");
Amitkumar Karwar7e174832014-09-18 07:18:50 -04002315 ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
2316 FW_DUMP_READ_DONE);
2317 if (ret) {
2318 dev_err(adapter->dev, "PCIE write err\n");
2319 goto done;
2320 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002321 break;
2322 }
2323
2324 dev_info(adapter->dev,
2325 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2326 entry->mem_ptr = vmalloc(memory_size + 1);
2327 entry->mem_size = memory_size;
2328 if (!entry->mem_ptr) {
2329 dev_err(adapter->dev,
2330 "Vmalloc %s failed\n", entry->mem_name);
2331 goto done;
2332 }
2333 dbg_ptr = entry->mem_ptr;
2334 end_ptr = dbg_ptr + memory_size;
2335
2336 doneflag = entry->done_flag;
Bing Zhao1d9e9542014-07-17 15:55:09 -07002337 dev_info(adapter->dev, "Start %s output, please wait...\n",
2338 entry->mem_name);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002339
2340 do {
2341 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2342 if (RDWR_STATUS_FAILURE == stat)
2343 goto done;
2344
2345 reg_start = creg->fw_dump_start;
2346 reg_end = creg->fw_dump_end;
2347 for (reg = reg_start; reg <= reg_end; reg++) {
2348 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
Amitkumar Karwar24716872014-09-18 08:04:01 -04002349 if (dbg_ptr < end_ptr) {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002350 dbg_ptr++;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002351 } else {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002352 dev_err(adapter->dev,
2353 "Allocated buf not enough\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002354 goto done;
2355 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002356 }
2357
2358 if (stat != RDWR_STATUS_DONE)
2359 continue;
2360
2361 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2362 entry->mem_name, dbg_ptr - entry->mem_ptr);
2363 break;
2364 } while (true);
2365 }
Bing Zhao1d9e9542014-07-17 15:55:09 -07002366 dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002367
2368 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2369
2370done:
2371 adapter->curr_mem_idx = 0;
2372}
2373
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002374static unsigned long iface_work_flags;
2375static struct mwifiex_adapter *save_adapter;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002376static void mwifiex_pcie_work(struct work_struct *work)
2377{
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002378 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002379 &iface_work_flags))
2380 mwifiex_pcie_fw_dump_work(save_adapter);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002381}
2382
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002383static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002384/* This function dumps FW information */
2385static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2386{
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002387 save_adapter = adapter;
2388 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002389 return;
2390
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002391 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002392
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002393 schedule_work(&pcie_work);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002394}
2395
Amitkumar Karward930fae2011-10-11 17:41:21 -07002396/*
2397 * This function initializes the PCI-E host memory space, WCB rings, etc.
2398 *
2399 * The following initializations steps are followed -
2400 * - Allocate TXBD ring buffers
2401 * - Allocate RXBD ring buffers
2402 * - Allocate event BD ring buffers
2403 * - Allocate command response ring buffer
2404 * - Allocate sleep cookie buffer
2405 */
2406static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2407{
2408 struct pcie_service_card *card = adapter->card;
2409 int ret;
2410 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002411 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002412
2413 pci_set_drvdata(pdev, card);
2414
2415 ret = pci_enable_device(pdev);
2416 if (ret)
2417 goto err_enable_dev;
2418
2419 pci_set_master(pdev);
2420
2421 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2422 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2423 if (ret) {
2424 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2425 goto err_set_dma_mask;
2426 }
2427
2428 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2429 if (ret) {
2430 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2431 goto err_set_dma_mask;
2432 }
2433
2434 ret = pci_request_region(pdev, 0, DRV_NAME);
2435 if (ret) {
2436 dev_err(adapter->dev, "req_reg(0) error\n");
2437 goto err_req_region0;
2438 }
2439 card->pci_mmap = pci_iomap(pdev, 0, 0);
2440 if (!card->pci_mmap) {
2441 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002442 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002443 goto err_iomap0;
2444 }
2445 ret = pci_request_region(pdev, 2, DRV_NAME);
2446 if (ret) {
2447 dev_err(adapter->dev, "req_reg(2) error\n");
2448 goto err_req_region2;
2449 }
2450 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2451 if (!card->pci_mmap1) {
2452 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002453 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002454 goto err_iomap2;
2455 }
2456
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002457 dev_dbg(adapter->dev,
2458 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2459 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002460
2461 card->cmdrsp_buf = NULL;
2462 ret = mwifiex_pcie_create_txbd_ring(adapter);
2463 if (ret)
2464 goto err_cre_txbd;
2465 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2466 if (ret)
2467 goto err_cre_rxbd;
2468 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2469 if (ret)
2470 goto err_cre_evtbd;
2471 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2472 if (ret)
2473 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002474 if (reg->sleep_cookie) {
2475 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2476 if (ret)
2477 goto err_alloc_cookie;
2478 } else {
2479 card->sleep_cookie_vbase = NULL;
2480 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002481 return ret;
2482
2483err_alloc_cookie:
2484 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2485err_alloc_cmdbuf:
2486 mwifiex_pcie_delete_evtbd_ring(adapter);
2487err_cre_evtbd:
2488 mwifiex_pcie_delete_rxbd_ring(adapter);
2489err_cre_rxbd:
2490 mwifiex_pcie_delete_txbd_ring(adapter);
2491err_cre_txbd:
2492 pci_iounmap(pdev, card->pci_mmap1);
2493err_iomap2:
2494 pci_release_region(pdev, 2);
2495err_req_region2:
2496 pci_iounmap(pdev, card->pci_mmap);
2497err_iomap0:
2498 pci_release_region(pdev, 0);
2499err_req_region0:
2500err_set_dma_mask:
2501 pci_disable_device(pdev);
2502err_enable_dev:
2503 pci_set_drvdata(pdev, NULL);
2504 return ret;
2505}
2506
2507/*
2508 * This function cleans up the allocated card buffers.
2509 *
2510 * The following are freed by this function -
2511 * - TXBD ring buffers
2512 * - RXBD ring buffers
2513 * - Event BD ring buffers
2514 * - Command response ring buffer
2515 * - Sleep cookie buffer
2516 */
2517static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2518{
2519 struct pcie_service_card *card = adapter->card;
2520 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002521 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002522
Amitkumar Karward930fae2011-10-11 17:41:21 -07002523 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002524 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002525 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002526 dev_err(adapter->dev,
2527 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002528 }
2529
2530 if (pdev) {
2531 pci_iounmap(pdev, card->pci_mmap);
2532 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002533 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002534 pci_release_region(pdev, 2);
2535 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002536 pci_set_drvdata(pdev, NULL);
2537 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002538 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002539}
2540
2541/*
2542 * This function registers the PCIE device.
2543 *
2544 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2545 */
2546static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2547{
2548 int ret;
2549 struct pcie_service_card *card = adapter->card;
2550 struct pci_dev *pdev = card->dev;
2551
2552 /* save adapter pointer in card */
2553 card->adapter = adapter;
2554
2555 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2556 "MRVL_PCIE", pdev);
2557 if (ret) {
2558 pr_err("request_irq failed: ret=%d\n", ret);
2559 adapter->card = NULL;
2560 return -1;
2561 }
2562
2563 adapter->dev = &pdev->dev;
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002564 adapter->tx_buf_size = card->pcie.tx_buf_size;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002565 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
2566 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
Avinash Patildd04e6a2013-02-08 18:18:06 -08002567 strcpy(adapter->fw_name, card->pcie.firmware);
Avinash Patil1fe192d2015-01-23 17:09:19 +05302568 adapter->ext_scan = card->pcie.can_ext_scan;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002569
2570 return 0;
2571}
2572
2573/*
2574 * This function unregisters the PCIE device.
2575 *
2576 * The PCIE IRQ is released, the function is disabled and driver
2577 * data is set to null.
2578 */
2579static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2580{
2581 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002582 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002583
2584 if (card) {
2585 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2586 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002587
Avinash Patil52301a82013-02-12 14:38:32 -08002588 reg = card->pcie.reg;
2589 if (reg->sleep_cookie)
2590 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2591
Avinash Patilfc331462013-01-03 21:21:30 -08002592 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2593 mwifiex_pcie_delete_evtbd_ring(adapter);
2594 mwifiex_pcie_delete_rxbd_ring(adapter);
2595 mwifiex_pcie_delete_txbd_ring(adapter);
2596 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002597 }
2598}
2599
2600static struct mwifiex_if_ops pcie_ops = {
2601 .init_if = mwifiex_pcie_init,
2602 .cleanup_if = mwifiex_pcie_cleanup,
2603 .check_fw_status = mwifiex_check_fw_status,
2604 .prog_fw = mwifiex_prog_fw_w_helper,
2605 .register_dev = mwifiex_register_dev,
2606 .unregister_dev = mwifiex_unregister_dev,
2607 .enable_int = mwifiex_pcie_enable_host_int,
2608 .process_int_status = mwifiex_process_int_status,
2609 .host_to_card = mwifiex_pcie_host_to_card,
2610 .wakeup = mwifiex_pm_wakeup_card,
2611 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2612
2613 /* PCIE specific */
2614 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2615 .event_complete = mwifiex_pcie_event_complete,
2616 .update_mp_end_port = NULL,
2617 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002618 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002619 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002620 .fw_dump = mwifiex_pcie_fw_dump,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002621};
2622
2623/*
2624 * This function initializes the PCIE driver module.
2625 *
2626 * This initiates the semaphore and registers the device with
2627 * PCIE bus.
2628 */
2629static int mwifiex_pcie_init_module(void)
2630{
2631 int ret;
2632
Avinash Patilca8f2112013-02-08 18:18:09 -08002633 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002634
2635 sema_init(&add_remove_card_sem, 1);
2636
2637 /* Clear the flag in case user removes the card. */
2638 user_rmmod = 0;
2639
2640 ret = pci_register_driver(&mwifiex_pcie);
2641 if (ret)
2642 pr_err("Driver register failed!\n");
2643 else
2644 pr_debug("info: Driver registered successfully!\n");
2645
2646 return ret;
2647}
2648
2649/*
2650 * This function cleans up the PCIE driver.
2651 *
2652 * The following major steps are followed for cleanup -
2653 * - Resume the device if its suspended
2654 * - Disconnect the device if connected
2655 * - Shutdown the firmware
2656 * - Unregister the device from PCIE bus.
2657 */
2658static void mwifiex_pcie_cleanup_module(void)
2659{
2660 if (!down_interruptible(&add_remove_card_sem))
2661 up(&add_remove_card_sem);
2662
2663 /* Set the flag as user is removing this module. */
2664 user_rmmod = 1;
2665
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002666 cancel_work_sync(&pcie_work);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002667 pci_unregister_driver(&mwifiex_pcie);
2668}
2669
2670module_init(mwifiex_pcie_init_module);
2671module_exit(mwifiex_pcie_cleanup_module);
2672
2673MODULE_AUTHOR("Marvell International Ltd.");
2674MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2675MODULE_VERSION(PCIE_VERSION);
2676MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002677MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2678MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);