blob: 3c3c4f197da867abd2cce54fc9818feaec28f5b7 [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
Avinash Patilfc331462013-01-03 21:21:30 -080040static int
41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
Aaron Durbindbccc922014-02-07 16:25:50 -080042 size_t size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070043{
Avinash Patilfc331462013-01-03 21:21:30 -080044 struct pcie_service_card *card = adapter->card;
Aaron Durbindbccc922014-02-07 16:25:50 -080045 struct mwifiex_dma_mapping mapping;
Amitkumar Karward930fae2011-10-11 17:41:21 -070046
Aaron Durbindbccc922014-02-07 16:25:50 -080047 mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
48 if (pci_dma_mapping_error(card->dev, mapping.addr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +053049 mwifiex_dbg(adapter, ERROR, "failed to map pci memory!\n");
Avinash Patilfc331462013-01-03 21:21:30 -080050 return -1;
51 }
Aaron Durbindbccc922014-02-07 16:25:50 -080052 mapping.len = size;
Chin-Ran Lobca463e2014-06-06 19:37:10 -070053 mwifiex_store_mapping(skb, &mapping);
Avinash Patilfc331462013-01-03 21:21:30 -080054 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070055}
56
Aaron Durbindbccc922014-02-07 16:25:50 -080057static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
58 struct sk_buff *skb, int flags)
59{
60 struct pcie_service_card *card = adapter->card;
61 struct mwifiex_dma_mapping mapping;
62
Chin-Ran Lobca463e2014-06-06 19:37:10 -070063 mwifiex_get_mapping(skb, &mapping);
Aaron Durbindbccc922014-02-07 16:25:50 -080064 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
65}
66
Amitkumar Karward930fae2011-10-11 17:41:21 -070067/*
68 * This function reads sleep cookie and checks if FW is ready
69 */
70static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
71{
72 u32 *cookie_addr;
73 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080074 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
75
76 if (!reg->sleep_cookie)
77 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070078
Avinash Patilfc331462013-01-03 21:21:30 -080079 if (card->sleep_cookie_vbase) {
80 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +053081 mwifiex_dbg(adapter, INFO,
82 "info: ACCESS_HW: sleep cookie=0x%x\n",
83 *cookie_addr);
Amitkumar Karward930fae2011-10-11 17:41:21 -070084 if (*cookie_addr == FW_AWAKE_COOKIE)
85 return true;
86 }
87
88 return false;
89}
90
Shuah Khan3266d732013-07-03 10:47:10 -060091#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -070092/*
Bing Zhaofcca8d52013-03-04 16:27:53 -080093 * Kernel needs to suspend all functions separately. Therefore all
94 * registered functions must have drivers with suspend and resume
95 * methods. Failing that the kernel simply removes the whole card.
96 *
97 * If already not suspended, this function allocates and sends a host
98 * sleep activate request to the firmware and turns off the traffic.
99 */
Shuah Khan3266d732013-07-03 10:47:10 -0600100static int mwifiex_pcie_suspend(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800101{
102 struct mwifiex_adapter *adapter;
103 struct pcie_service_card *card;
104 int hs_actived;
Shuah Khan3266d732013-07-03 10:47:10 -0600105 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800106
107 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900108 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800109 if (!card || !card->adapter) {
110 pr_err("Card or adapter structure is not valid\n");
111 return 0;
112 }
113 } else {
114 pr_err("PCIE device is not specified\n");
115 return 0;
116 }
117
118 adapter = card->adapter;
119
120 hs_actived = mwifiex_enable_hs(adapter);
121
122 /* Indicate device suspended */
123 adapter->is_suspended = true;
Amitkumar Karwarc0dbba62014-03-25 19:01:20 -0700124 adapter->hs_enabling = false;
Bing Zhaofcca8d52013-03-04 16:27:53 -0800125
126 return 0;
127}
128
129/*
130 * Kernel needs to suspend all functions separately. Therefore all
131 * registered functions must have drivers with suspend and resume
132 * methods. Failing that the kernel simply removes the whole card.
133 *
134 * If already not resumed, this function turns on the traffic and
135 * sends a host sleep cancel request to the firmware.
136 */
Shuah Khan3266d732013-07-03 10:47:10 -0600137static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800138{
139 struct mwifiex_adapter *adapter;
140 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600141 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800142
143 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900144 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800145 if (!card || !card->adapter) {
146 pr_err("Card or adapter structure is not valid\n");
147 return 0;
148 }
149 } else {
150 pr_err("PCIE device is not specified\n");
151 return 0;
152 }
153
154 adapter = card->adapter;
155
156 if (!adapter->is_suspended) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530157 mwifiex_dbg(adapter, WARN,
158 "Device already resumed\n");
Bing Zhaofcca8d52013-03-04 16:27:53 -0800159 return 0;
160 }
161
162 adapter->is_suspended = false;
163
164 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
165 MWIFIEX_ASYNC_CMD);
166
167 return 0;
168}
Bing Zhao8509e822013-03-04 16:27:54 -0800169#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800170
171/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700172 * This function probes an mwifiex device and registers it. It allocates
173 * the card structure, enables PCIE function number and initiates the
174 * device registration and initialization procedure by adding a logical
175 * interface.
176 */
177static int mwifiex_pcie_probe(struct pci_dev *pdev,
178 const struct pci_device_id *ent)
179{
180 struct pcie_service_card *card;
181
182 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700183 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700184
185 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000186 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700187 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700188
189 card->dev = pdev;
190
Avinash Patildd04e6a2013-02-08 18:18:06 -0800191 if (ent->driver_data) {
192 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800193 card->pcie.reg = data->reg;
194 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
Amitkumar Karwar828cf222014-02-27 19:35:13 -0800195 card->pcie.tx_buf_size = data->tx_buf_size;
Avinash Patilb4e8aeb2015-02-11 23:12:26 +0530196 card->pcie.can_dump_fw = data->can_dump_fw;
Xinming Hu50632092016-02-02 22:05:06 -0800197 card->pcie.mem_type_mapping_tbl = data->mem_type_mapping_tbl;
198 card->pcie.num_mem_types = data->num_mem_types;
Avinash Patil1fe192d2015-01-23 17:09:19 +0530199 card->pcie.can_ext_scan = data->can_ext_scan;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800200 }
201
Amitkumar Karward930fae2011-10-11 17:41:21 -0700202 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
203 MWIFIEX_PCIE)) {
204 pr_err("%s failed\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700205 return -1;
206 }
207
208 return 0;
209}
210
211/*
212 * This function removes the interface and frees up the card structure.
213 */
214static void mwifiex_pcie_remove(struct pci_dev *pdev)
215{
216 struct pcie_service_card *card;
217 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700218 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700219
220 card = pci_get_drvdata(pdev);
221 if (!card)
222 return;
223
224 adapter = card->adapter;
225 if (!adapter || !adapter->priv_num)
226 return;
227
Xinming Hucf5383b2016-09-02 13:05:06 +0530228 if (user_rmmod && !adapter->mfg_mode) {
Shuah Khan3266d732013-07-03 10:47:10 -0600229#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700230 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600231 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700232#endif
233
Amitkumar Karwar848819f2014-02-27 19:35:17 -0800234 mwifiex_deauthenticate_all(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700235
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700236 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700237
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700238 mwifiex_disable_auto_ds(priv);
239
240 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700241 }
242
243 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700244}
245
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700246static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
247{
248 user_rmmod = 1;
249 mwifiex_pcie_remove(pdev);
250
251 return;
252}
253
Benoit Taine9baa3c32014-08-08 15:56:03 +0200254static const struct pci_device_id mwifiex_ids[] = {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700255 {
256 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
257 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Zhaoyang Liu6d85ef02015-08-05 06:09:40 -0700258 .driver_data = (unsigned long)&mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700259 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800260 {
261 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
262 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Zhaoyang Liu6d85ef02015-08-05 06:09:40 -0700263 .driver_data = (unsigned long)&mwifiex_pcie8897,
264 },
265 {
266 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8997,
267 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
268 .driver_data = (unsigned long)&mwifiex_pcie8997,
Avinash Patilca8f2112013-02-08 18:18:09 -0800269 },
Shengzhen Lia362e162016-04-05 01:04:36 -0700270 {
271 PCIE_VENDOR_ID_V2_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8997,
272 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
273 .driver_data = (unsigned long)&mwifiex_pcie8997,
274 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700275 {},
276};
277
278MODULE_DEVICE_TABLE(pci, mwifiex_ids);
279
Amitkumar Karwar4c5dae52016-07-26 19:31:44 +0530280static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
281{
282 struct mwifiex_adapter *adapter;
283 struct pcie_service_card *card;
284
285 if (!pdev) {
286 pr_err("%s: PCIe device is not specified\n", __func__);
287 return;
288 }
289
290 card = (struct pcie_service_card *)pci_get_drvdata(pdev);
291 if (!card || !card->adapter) {
292 pr_err("%s: Card or adapter structure is not valid (%ld)\n",
293 __func__, (long)card);
294 return;
295 }
296
297 adapter = card->adapter;
298 mwifiex_dbg(adapter, INFO,
299 "%s: vendor=0x%4.04x device=0x%4.04x rev=%d %s\n",
300 __func__, pdev->vendor, pdev->device,
301 pdev->revision,
302 prepare ? "Pre-FLR" : "Post-FLR");
303
304 if (prepare) {
305 /* Kernel would be performing FLR after this notification.
306 * Cleanup all software without cleaning anything related to
307 * PCIe and HW.
308 */
309 mwifiex_do_flr(adapter, prepare);
310 adapter->surprise_removed = true;
311 } else {
312 /* Kernel stores and restores PCIe function context before and
313 * after performing FLR respectively. Reconfigure the software
314 * and firmware including firmware redownload
315 */
316 adapter->surprise_removed = false;
317 mwifiex_do_flr(adapter, prepare);
318 }
319 mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
320}
321
322static const struct pci_error_handlers mwifiex_pcie_err_handler[] = {
323 { .reset_notify = mwifiex_pcie_reset_notify, },
324};
325
Shuah Khan3266d732013-07-03 10:47:10 -0600326#ifdef CONFIG_PM_SLEEP
327/* Power Management Hooks */
328static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
329 mwifiex_pcie_resume);
330#endif
331
Amitkumar Karward930fae2011-10-11 17:41:21 -0700332/* PCI Device Driver */
333static struct pci_driver __refdata mwifiex_pcie = {
334 .name = "mwifiex_pcie",
335 .id_table = mwifiex_ids,
336 .probe = mwifiex_pcie_probe,
337 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600338#ifdef CONFIG_PM_SLEEP
339 .driver = {
340 .pm = &mwifiex_pcie_pm_ops,
341 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700342#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700343 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karwar4c5dae52016-07-26 19:31:44 +0530344 .err_handler = mwifiex_pcie_err_handler,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700345};
346
347/*
348 * This function writes data into PCIE card register.
349 */
350static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
351{
352 struct pcie_service_card *card = adapter->card;
353
354 iowrite32(data, card->pci_mmap1 + reg);
355
356 return 0;
357}
358
359/*
360 * This function reads data from PCIE card register.
361 */
362static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
363{
364 struct pcie_service_card *card = adapter->card;
365
366 *data = ioread32(card->pci_mmap1 + reg);
Xinming Huaf051482016-02-02 22:05:03 -0800367 if (*data == 0xffffffff)
368 return 0xffffffff;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700369
370 return 0;
371}
372
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700373/* This function reads u8 data from PCIE card register. */
374static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
375 int reg, u8 *data)
376{
377 struct pcie_service_card *card = adapter->card;
378
379 *data = ioread8(card->pci_mmap1 + reg);
380
381 return 0;
382}
383
Amitkumar Karward930fae2011-10-11 17:41:21 -0700384/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700385 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700386 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700387static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700388{
389 int i = 0;
390
Avinash Patilc0880a22013-03-22 21:49:07 -0700391 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700392 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700393 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700394 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800395 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700396 break;
397 }
398
Avinash Patilc0880a22013-03-22 21:49:07 -0700399 return;
400}
401
Avinash Patilc4bc9802014-03-18 22:19:17 -0700402static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
403 u32 max_delay_loop_cnt)
404{
405 struct pcie_service_card *card = adapter->card;
406 u8 *buffer;
407 u32 sleep_cookie, count;
408
409 for (count = 0; count < max_delay_loop_cnt; count++) {
410 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
411 sleep_cookie = *(u32 *)buffer;
412
413 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530414 mwifiex_dbg(adapter, INFO,
415 "sleep cookie found at count %d\n", count);
Avinash Patilc4bc9802014-03-18 22:19:17 -0700416 break;
417 }
418 usleep_range(20, 30);
419 }
420
421 if (count >= max_delay_loop_cnt)
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530422 mwifiex_dbg(adapter, INFO,
423 "max count reached while accessing sleep cookie\n");
Avinash Patilc4bc9802014-03-18 22:19:17 -0700424}
425
Avinash Patilc0880a22013-03-22 21:49:07 -0700426/* This function wakes up the card by reading fw_status register. */
427static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
428{
429 u32 fw_status;
430 struct pcie_service_card *card = adapter->card;
431 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
432
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530433 mwifiex_dbg(adapter, EVENT,
434 "event: Wakeup device...\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700435
Avinash Patilc0880a22013-03-22 21:49:07 -0700436 if (reg->sleep_cookie)
437 mwifiex_pcie_dev_wakeup_delay(adapter);
438
439 /* Reading fw_status register will wakeup device */
440 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530441 mwifiex_dbg(adapter, ERROR,
442 "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700443 return -1;
444 }
445
Avinash Patilc0880a22013-03-22 21:49:07 -0700446 if (reg->sleep_cookie) {
447 mwifiex_pcie_dev_wakeup_delay(adapter);
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530448 mwifiex_dbg(adapter, INFO,
449 "PCIE wakeup: Setting PS_STATE_AWAKE\n");
Avinash Patilc0880a22013-03-22 21:49:07 -0700450 adapter->ps_state = PS_STATE_AWAKE;
451 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700452
453 return 0;
454}
455
456/*
457 * This function is called after the card has woken up.
458 *
459 * The card configuration register is reset.
460 */
461static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
462{
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530463 mwifiex_dbg(adapter, CMD,
464 "cmd: Wakeup device completed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700465
466 return 0;
467}
468
469/*
470 * This function disables the host interrupt.
471 *
472 * The host interrupt mask is read, the disable bit is reset and
473 * written back to the card host interrupt mask register.
474 */
475static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
476{
477 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
478 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
479 0x00000000)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530480 mwifiex_dbg(adapter, ERROR,
481 "Disable host interrupt failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700482 return -1;
483 }
484 }
485
486 return 0;
487}
488
Brian Norrisd41376c2016-06-30 15:21:02 -0700489static void mwifiex_pcie_disable_host_int_noerr(struct mwifiex_adapter *adapter)
490{
491 WARN_ON(mwifiex_pcie_disable_host_int(adapter));
492}
493
Amitkumar Karward930fae2011-10-11 17:41:21 -0700494/*
495 * This function enables the host interrupt.
496 *
497 * The host interrupt enable mask is written to the card
498 * host interrupt mask register.
499 */
500static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
501{
502 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
503 /* Simply write the mask to the register */
504 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
505 HOST_INTR_MASK)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530506 mwifiex_dbg(adapter, ERROR,
507 "Enable host interrupt failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700508 return -1;
509 }
510 }
511
512 return 0;
513}
514
515/*
Avinash Patil07324842013-02-08 18:18:07 -0800516 * This function initializes TX buffer ring descriptors
517 */
518static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
519{
520 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800521 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800522 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800523 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800524 int i;
525
526 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
527 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800528 if (reg->pfu_enabled) {
529 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
530 (sizeof(*desc2) * i);
531 desc2 = card->txbd_ring[i];
532 memset(desc2, 0, sizeof(*desc2));
533 } else {
534 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
535 (sizeof(*desc) * i);
536 desc = card->txbd_ring[i];
537 memset(desc, 0, sizeof(*desc));
538 }
Avinash Patil07324842013-02-08 18:18:07 -0800539 }
540
541 return 0;
542}
543
544/* This function initializes RX buffer ring descriptors. Each SKB is allocated
545 * here and after mapping PCI memory, its physical address is assigned to
546 * PCIE Rx buffer descriptor's physical address.
547 */
548static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
549{
550 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800551 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800552 struct sk_buff *skb;
553 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800554 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800555 dma_addr_t buf_pa;
556 int i;
557
558 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
559 /* Allocate skb here so that firmware can DMA data from it */
Avinash Patil62159942015-03-13 17:37:52 +0530560 skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
Mathias Krause5c87a552016-05-21 15:43:31 +0200561 GFP_KERNEL);
Avinash Patil07324842013-02-08 18:18:07 -0800562 if (!skb) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530563 mwifiex_dbg(adapter, ERROR,
564 "Unable to allocate skb for RX ring.\n");
Avinash Patil07324842013-02-08 18:18:07 -0800565 kfree(card->rxbd_ring_vbase);
566 return -ENOMEM;
567 }
568
569 if (mwifiex_map_pci_memory(adapter, skb,
570 MWIFIEX_RX_DATA_BUF_SIZE,
571 PCI_DMA_FROMDEVICE))
572 return -1;
573
Aaron Durbindbccc922014-02-07 16:25:50 -0800574 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800575
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530576 mwifiex_dbg(adapter, INFO,
577 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
578 skb, skb->len, skb->data, (u32)buf_pa,
579 (u32)((u64)buf_pa >> 32));
Avinash Patil07324842013-02-08 18:18:07 -0800580
581 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800582 if (reg->pfu_enabled) {
583 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
584 (sizeof(*desc2) * i);
585 desc2 = card->rxbd_ring[i];
586 desc2->paddr = buf_pa;
587 desc2->len = (u16)skb->len;
588 desc2->frag_len = (u16)skb->len;
589 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
590 desc2->offset = 0;
591 } else {
592 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
593 (sizeof(*desc) * i));
594 desc = card->rxbd_ring[i];
595 desc->paddr = buf_pa;
596 desc->len = (u16)skb->len;
597 desc->flags = 0;
598 }
Avinash Patil07324842013-02-08 18:18:07 -0800599 }
600
601 return 0;
602}
603
604/* This function initializes event buffer ring descriptors. Each SKB is
605 * allocated here and after mapping PCI memory, its physical address is assigned
606 * to PCIE Rx buffer descriptor's physical address
607 */
608static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
609{
610 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800611 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800612 struct sk_buff *skb;
613 dma_addr_t buf_pa;
614 int i;
615
616 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
617 /* Allocate skb here so that firmware can DMA data from it */
618 skb = dev_alloc_skb(MAX_EVENT_SIZE);
619 if (!skb) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530620 mwifiex_dbg(adapter, ERROR,
621 "Unable to allocate skb for EVENT buf.\n");
Avinash Patil07324842013-02-08 18:18:07 -0800622 kfree(card->evtbd_ring_vbase);
623 return -ENOMEM;
624 }
625 skb_put(skb, MAX_EVENT_SIZE);
626
627 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
628 PCI_DMA_FROMDEVICE))
629 return -1;
630
Aaron Durbindbccc922014-02-07 16:25:50 -0800631 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800632
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530633 mwifiex_dbg(adapter, EVENT,
634 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
635 skb, skb->len, skb->data, (u32)buf_pa,
636 (u32)((u64)buf_pa >> 32));
Avinash Patil07324842013-02-08 18:18:07 -0800637
638 card->evt_buf_list[i] = skb;
639 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
640 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800641 desc = card->evtbd_ring[i];
642 desc->paddr = buf_pa;
643 desc->len = (u16)skb->len;
644 desc->flags = 0;
645 }
646
647 return 0;
648}
649
650/* This function cleans up TX buffer rings. If any of the buffer list has valid
651 * SKB address, associated SKB is freed.
652 */
653static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
654{
655 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800656 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800657 struct sk_buff *skb;
658 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800659 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800660 int i;
661
662 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800663 if (reg->pfu_enabled) {
664 desc2 = card->txbd_ring[i];
665 if (card->tx_buf_list[i]) {
666 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800667 mwifiex_unmap_pci_memory(adapter, skb,
668 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800669 dev_kfree_skb_any(skb);
670 }
671 memset(desc2, 0, sizeof(*desc2));
672 } else {
673 desc = card->txbd_ring[i];
674 if (card->tx_buf_list[i]) {
675 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800676 mwifiex_unmap_pci_memory(adapter, skb,
677 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800678 dev_kfree_skb_any(skb);
679 }
680 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800681 }
682 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800683 }
684
685 return;
686}
687
688/* This function cleans up RX buffer rings. If any of the buffer list has valid
689 * SKB address, associated SKB is freed.
690 */
691static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
692{
693 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800694 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800695 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800696 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800697 struct sk_buff *skb;
698 int i;
699
700 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800701 if (reg->pfu_enabled) {
702 desc2 = card->rxbd_ring[i];
703 if (card->rx_buf_list[i]) {
704 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800705 mwifiex_unmap_pci_memory(adapter, skb,
706 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800707 dev_kfree_skb_any(skb);
708 }
709 memset(desc2, 0, sizeof(*desc2));
710 } else {
711 desc = card->rxbd_ring[i];
712 if (card->rx_buf_list[i]) {
713 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800714 mwifiex_unmap_pci_memory(adapter, skb,
715 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800716 dev_kfree_skb_any(skb);
717 }
718 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800719 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800720 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800721 }
722
723 return;
724}
725
726/* This function cleans up event buffer rings. If any of the buffer list has
727 * valid SKB address, associated SKB is freed.
728 */
729static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
730{
731 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800732 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800733 struct sk_buff *skb;
734 int i;
735
736 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
737 desc = card->evtbd_ring[i];
738 if (card->evt_buf_list[i]) {
739 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800740 mwifiex_unmap_pci_memory(adapter, skb,
741 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800742 dev_kfree_skb_any(skb);
743 }
744 card->evt_buf_list[i] = NULL;
745 memset(desc, 0, sizeof(*desc));
746 }
747
748 return;
749}
750
751/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700752 */
753static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
754{
755 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800756 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700757
758 /*
759 * driver maintaines the write pointer and firmware maintaines the read
760 * pointer. The write pointer starts at 0 (zero) while the read pointer
761 * starts at zero with rollover bit set
762 */
763 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800764
765 if (reg->pfu_enabled)
766 card->txbd_rdptr = 0;
767 else
768 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700769
770 /* allocate shared memory for the BD ring and divide the same in to
771 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800772 if (reg->pfu_enabled)
773 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
774 MWIFIEX_MAX_TXRX_BD;
775 else
776 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
777 MWIFIEX_MAX_TXRX_BD;
778
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530779 mwifiex_dbg(adapter, INFO,
780 "info: txbd_ring: Allocating %d bytes\n",
781 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800782 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
783 card->txbd_ring_size,
784 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700785 if (!card->txbd_ring_vbase) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530786 mwifiex_dbg(adapter, ERROR,
787 "allocate consistent memory (%d bytes) failed!\n",
788 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800789 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700790 }
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530791 mwifiex_dbg(adapter, DATA,
792 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
793 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
794 (u32)((u64)card->txbd_ring_pbase >> 32),
795 card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700796
Avinash Patil07324842013-02-08 18:18:07 -0800797 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700798}
799
800static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
801{
802 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800803 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700804
Avinash Patil07324842013-02-08 18:18:07 -0800805 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700806
Avinash Patilfc331462013-01-03 21:21:30 -0800807 if (card->txbd_ring_vbase)
808 pci_free_consistent(card->dev, card->txbd_ring_size,
809 card->txbd_ring_vbase,
810 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700811 card->txbd_ring_size = 0;
812 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800813 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700814 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800815 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700816
817 return 0;
818}
819
820/*
821 * This function creates buffer descriptor ring for RX
822 */
823static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
824{
825 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800826 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700827
828 /*
829 * driver maintaines the read pointer and firmware maintaines the write
830 * pointer. The write pointer starts at 0 (zero) while the read pointer
831 * starts at zero with rollover bit set
832 */
833 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800834 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700835
Avinash Patilca8f2112013-02-08 18:18:09 -0800836 if (reg->pfu_enabled)
837 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
838 MWIFIEX_MAX_TXRX_BD;
839 else
840 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
841 MWIFIEX_MAX_TXRX_BD;
842
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530843 mwifiex_dbg(adapter, INFO,
844 "info: rxbd_ring: Allocating %d bytes\n",
845 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800846 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
847 card->rxbd_ring_size,
848 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700849 if (!card->rxbd_ring_vbase) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530850 mwifiex_dbg(adapter, ERROR,
851 "allocate consistent memory (%d bytes) failed!\n",
852 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800853 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700854 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700855
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530856 mwifiex_dbg(adapter, DATA,
857 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
858 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
859 (u32)((u64)card->rxbd_ring_pbase >> 32),
860 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700861
Avinash Patil07324842013-02-08 18:18:07 -0800862 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700863}
864
865/*
866 * This function deletes Buffer descriptor ring for RX
867 */
868static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
869{
870 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800871 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700872
Avinash Patil07324842013-02-08 18:18:07 -0800873 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700874
Avinash Patilfc331462013-01-03 21:21:30 -0800875 if (card->rxbd_ring_vbase)
876 pci_free_consistent(card->dev, card->rxbd_ring_size,
877 card->rxbd_ring_vbase,
878 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700879 card->rxbd_ring_size = 0;
880 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800881 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700882 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800883 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700884
885 return 0;
886}
887
888/*
889 * This function creates buffer descriptor ring for Events
890 */
891static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
892{
893 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800894 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700895
896 /*
897 * driver maintaines the read pointer and firmware maintaines the write
898 * pointer. The write pointer starts at 0 (zero) while the read pointer
899 * starts at zero with rollover bit set
900 */
901 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800902 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700903
Avinash Patile05dc3e2013-02-08 18:18:08 -0800904 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800905 MWIFIEX_MAX_EVT_BD;
906
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530907 mwifiex_dbg(adapter, INFO,
908 "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700909 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800910 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
911 card->evtbd_ring_size,
912 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700913 if (!card->evtbd_ring_vbase) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530914 mwifiex_dbg(adapter, ERROR,
915 "allocate consistent memory (%d bytes) failed!\n",
916 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800917 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700918 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700919
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530920 mwifiex_dbg(adapter, EVENT,
921 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
922 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
923 (u32)((u64)card->evtbd_ring_pbase >> 32),
924 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700925
Avinash Patil07324842013-02-08 18:18:07 -0800926 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700927}
928
929/*
930 * This function deletes Buffer descriptor ring for Events
931 */
932static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
933{
934 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800935 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700936
Avinash Patil07324842013-02-08 18:18:07 -0800937 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700938
Avinash Patilfc331462013-01-03 21:21:30 -0800939 if (card->evtbd_ring_vbase)
940 pci_free_consistent(card->dev, card->evtbd_ring_size,
941 card->evtbd_ring_vbase,
942 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700943 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800944 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700945 card->evtbd_ring_size = 0;
946 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800947 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700948
949 return 0;
950}
951
952/*
953 * This function allocates a buffer for CMDRSP
954 */
955static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
956{
957 struct pcie_service_card *card = adapter->card;
958 struct sk_buff *skb;
959
960 /* Allocate memory for receiving command response data */
961 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
962 if (!skb) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +0530963 mwifiex_dbg(adapter, ERROR,
964 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700965 return -ENOMEM;
966 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700967 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800968 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
969 PCI_DMA_FROMDEVICE))
970 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700971
Avinash Patilfc331462013-01-03 21:21:30 -0800972 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700973
974 return 0;
975}
976
977/*
978 * This function deletes a buffer for CMDRSP
979 */
980static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
981{
982 struct pcie_service_card *card;
983
984 if (!adapter)
985 return 0;
986
987 card = adapter->card;
988
Avinash Patilfc331462013-01-03 21:21:30 -0800989 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800990 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
991 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700992 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800993 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700994
Avinash Patilfc331462013-01-03 21:21:30 -0800995 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800996 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
997 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800998 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700999 return 0;
1000}
1001
1002/*
1003 * This function allocates a buffer for sleep cookie
1004 */
1005static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
1006{
Amitkumar Karward930fae2011-10-11 17:41:21 -07001007 struct pcie_service_card *card = adapter->card;
1008
Avinash Patilfc331462013-01-03 21:21:30 -08001009 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
1010 &card->sleep_cookie_pbase);
1011 if (!card->sleep_cookie_vbase) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301012 mwifiex_dbg(adapter, ERROR,
1013 "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001014 return -ENOMEM;
1015 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001016 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -08001017 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001018
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301019 mwifiex_dbg(adapter, INFO,
1020 "alloc_scook: sleep cookie=0x%x\n",
1021 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001022
1023 return 0;
1024}
1025
1026/*
1027 * This function deletes buffer for sleep cookie
1028 */
1029static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
1030{
1031 struct pcie_service_card *card;
1032
1033 if (!adapter)
1034 return 0;
1035
1036 card = adapter->card;
1037
Avinash Patilfc331462013-01-03 21:21:30 -08001038 if (card && card->sleep_cookie_vbase) {
1039 pci_free_consistent(card->dev, sizeof(u32),
1040 card->sleep_cookie_vbase,
1041 card->sleep_cookie_pbase);
1042 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001043 }
1044
1045 return 0;
1046}
1047
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08001048/* This function flushes the TX buffer descriptor ring
1049 * This function defined as handler is also called while cleaning TXRX
1050 * during disconnect/ bss stop.
1051 */
1052static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
1053{
1054 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08001055
Avinash Patil48f4d912013-02-20 21:12:58 -08001056 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08001057 card->txbd_flush = 1;
1058 /* write pointer already set at last send
1059 * send dnld-rdy intr again, wait for completion.
1060 */
1061 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1062 CPU_INTR_DNLD_RDY)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301063 mwifiex_dbg(adapter, ERROR,
1064 "failed to assert dnld-rdy interrupt.\n");
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08001065 return -1;
1066 }
1067 }
1068 return 0;
1069}
1070
Amitkumar Karward930fae2011-10-11 17:41:21 -07001071/*
Avinash Patile7f767a2013-01-03 21:21:32 -08001072 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -07001073 */
Avinash Patile7f767a2013-01-03 21:21:32 -08001074static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001075{
Avinash Patile7f767a2013-01-03 21:21:32 -08001076 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -08001077 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001078 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001079 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001080 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001081 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001082
1083 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1084 mwifiex_pm_wakeup_card(adapter);
1085
1086 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001087 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301088 mwifiex_dbg(adapter, ERROR,
1089 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001090 return -1;
1091 }
1092
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301093 mwifiex_dbg(adapter, DATA,
1094 "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
1095 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001096
Avinash Patilca8f2112013-02-08 18:18:09 -08001097 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001098 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001099 while (((card->txbd_rdptr & reg->tx_mask) !=
1100 (rdptr & reg->tx_mask)) ||
1101 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
1102 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -08001103 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
1104 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001105
1106 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -08001107
Avinash Patile7f767a2013-01-03 21:21:32 -08001108 if (skb) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301109 mwifiex_dbg(adapter, DATA,
1110 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
1111 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -08001112 mwifiex_unmap_pci_memory(adapter, skb,
1113 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001114
1115 unmap_count++;
1116
1117 if (card->txbd_flush)
1118 mwifiex_write_data_complete(adapter, skb, 0,
1119 -1);
1120 else
1121 mwifiex_write_data_complete(adapter, skb, 0, 0);
1122 }
1123
1124 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001125
1126 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001127 desc2 = card->txbd_ring[wrdoneidx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001128 memset(desc2, 0, sizeof(*desc2));
1129 } else {
1130 desc = card->txbd_ring[wrdoneidx];
1131 memset(desc, 0, sizeof(*desc));
1132 }
1133 switch (card->dev->device) {
1134 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1135 card->txbd_rdptr++;
1136 break;
1137 case PCIE_DEVICE_ID_MARVELL_88W8897:
Zhaoyang Liu6d85ef02015-08-05 06:09:40 -07001138 case PCIE_DEVICE_ID_MARVELL_88W8997:
Avinash Patilca8f2112013-02-08 18:18:09 -08001139 card->txbd_rdptr += reg->ring_tx_start_ptr;
1140 break;
1141 }
1142
Avinash Patile7f767a2013-01-03 21:21:32 -08001143
Avinash Patildd04e6a2013-02-08 18:18:06 -08001144 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001145 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001146 reg->tx_rollover_ind) ^
1147 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001148 }
1149
1150 if (unmap_count)
1151 adapter->data_sent = false;
1152
1153 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001154 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001155 card->txbd_flush = 0;
1156 else
1157 mwifiex_clean_pcie_ring_buf(adapter);
1158 }
1159
1160 return 0;
1161}
1162
1163/* This function sends data buffer to device. First 4 bytes of payload
1164 * are filled with payload length and payload type. Then this payload
1165 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1166 * Download ready interrupt to FW is deffered if Tx ring is not full and
1167 * additional payload can be accomodated.
Avinash Patil8d767dc2014-05-13 19:50:13 -07001168 * Caller must ensure tx_param parameter to this function is not NULL.
Avinash Patile7f767a2013-01-03 21:21:32 -08001169 */
1170static int
1171mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1172 struct mwifiex_tx_param *tx_param)
1173{
1174 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001175 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001176 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001177 int ret;
1178 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001179 struct mwifiex_pcie_buf_desc *desc = NULL;
1180 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001181 __le16 *tmp;
1182
1183 if (!(skb->data && skb->len)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301184 mwifiex_dbg(adapter, ERROR,
1185 "%s(): invalid parameter <%p, %#x>\n",
1186 __func__, skb->data, skb->len);
Avinash Patile7f767a2013-01-03 21:21:32 -08001187 return -1;
1188 }
1189
1190 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1191 mwifiex_pm_wakeup_card(adapter);
1192
Avinash Patilca8f2112013-02-08 18:18:09 -08001193 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301194 mwifiex_dbg(adapter, DATA,
1195 "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001196 card->txbd_rdptr, card->txbd_wrptr);
1197 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001198 u8 *payload;
1199
1200 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001201 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001202 tmp = (__le16 *)&payload[0];
1203 *tmp = cpu_to_le16((u16)skb->len);
1204 tmp = (__le16 *)&payload[2];
1205 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001206
Aaron Durbindbccc922014-02-07 16:25:50 -08001207 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001208 PCI_DMA_TODEVICE))
1209 return -1;
1210
Avinash Patilca8f2112013-02-08 18:18:09 -08001211 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001212 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001213 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001214
Avinash Patilca8f2112013-02-08 18:18:09 -08001215 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001216 desc2 = card->txbd_ring[wrindx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001217 desc2->paddr = buf_pa;
1218 desc2->len = (u16)skb->len;
1219 desc2->frag_len = (u16)skb->len;
1220 desc2->offset = 0;
1221 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1222 MWIFIEX_BD_FLAG_LAST_DESC;
1223 } else {
1224 desc = card->txbd_ring[wrindx];
1225 desc->paddr = buf_pa;
1226 desc->len = (u16)skb->len;
1227 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1228 MWIFIEX_BD_FLAG_LAST_DESC;
1229 }
1230
1231 switch (card->dev->device) {
1232 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1233 card->txbd_wrptr++;
1234 break;
1235 case PCIE_DEVICE_ID_MARVELL_88W8897:
Zhaoyang Liu6d85ef02015-08-05 06:09:40 -07001236 case PCIE_DEVICE_ID_MARVELL_88W8997:
Avinash Patilca8f2112013-02-08 18:18:09 -08001237 card->txbd_wrptr += reg->ring_tx_start_ptr;
1238 break;
1239 }
1240
1241 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001242 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001243 reg->tx_rollover_ind) ^
1244 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001245
Avinash Patilca8f2112013-02-08 18:18:09 -08001246 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001247 /* Write the TX ring write pointer in to reg->tx_wrptr */
1248 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001249 card->txbd_wrptr | rx_val)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301250 mwifiex_dbg(adapter, ERROR,
1251 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001252 ret = -1;
1253 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001254 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001255 if ((mwifiex_pcie_txbd_not_full(card)) &&
1256 tx_param->next_pkt_len) {
1257 /* have more packets and TxBD still can hold more */
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301258 mwifiex_dbg(adapter, DATA,
1259 "SEND DATA: delay dnld-rdy interrupt.\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001260 adapter->data_sent = false;
1261 } else {
1262 /* Send the TX ready interrupt */
1263 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1264 CPU_INTR_DNLD_RDY)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301265 mwifiex_dbg(adapter, ERROR,
1266 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001267 ret = -1;
1268 goto done_unmap;
1269 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001270 }
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301271 mwifiex_dbg(adapter, DATA,
1272 "info: SEND DATA: Updated <Rd: %#x, Wr:\t"
1273 "%#x> and sent packet to firmware successfully\n",
1274 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001275 } else {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301276 mwifiex_dbg(adapter, DATA,
1277 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001278 adapter->data_sent = true;
1279 /* Send the TX ready interrupt */
1280 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1281 CPU_INTR_DNLD_RDY))
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301282 mwifiex_dbg(adapter, ERROR,
1283 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001284 return -EBUSY;
1285 }
1286
Avinash Patile7f767a2013-01-03 21:21:32 -08001287 return -EINPROGRESS;
1288done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001289 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001290 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001291 if (reg->pfu_enabled)
1292 memset(desc2, 0, sizeof(*desc2));
1293 else
1294 memset(desc, 0, sizeof(*desc));
1295
Avinash Patile7f767a2013-01-03 21:21:32 -08001296 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001297}
1298
1299/*
1300 * This function handles received buffer ring and
1301 * dispatches packets to upper
1302 */
1303static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1304{
1305 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001306 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001307 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001308 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001309 int ret = 0;
1310 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001311 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001312 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001313
Avinash Patile7f767a2013-01-03 21:21:32 -08001314 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1315 mwifiex_pm_wakeup_card(adapter);
1316
Amitkumar Karward930fae2011-10-11 17:41:21 -07001317 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001318 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301319 mwifiex_dbg(adapter, ERROR,
1320 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001321 ret = -1;
1322 goto done;
1323 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001324 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001325
Avinash Patildd04e6a2013-02-08 18:18:06 -08001326 while (((wrptr & reg->rx_mask) !=
1327 (card->rxbd_rdptr & reg->rx_mask)) ||
1328 ((wrptr & reg->rx_rollover_ind) ==
1329 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001330 struct sk_buff *skb_data;
1331 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001332 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001333
Avinash Patildd04e6a2013-02-08 18:18:06 -08001334 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001335 skb_data = card->rx_buf_list[rd_index];
1336
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001337 /* If skb allocation was failed earlier for Rx packet,
1338 * rx_buf_list[rd_index] would have been left with a NULL.
1339 */
1340 if (!skb_data)
1341 return -ENOMEM;
1342
Aaron Durbindbccc922014-02-07 16:25:50 -08001343 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001344 card->rx_buf_list[rd_index] = NULL;
1345
Amitkumar Karward930fae2011-10-11 17:41:21 -07001346 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001347 * first 2 bytes for len, next 2 bytes is for type
1348 */
1349 pkt_len = *((__le16 *)skb_data->data);
1350 rx_len = le16_to_cpu(pkt_len);
Avinash Patil42a028a2014-09-12 20:08:47 +05301351 if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
1352 rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301353 mwifiex_dbg(adapter, ERROR,
1354 "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
1355 rx_len, card->rxbd_rdptr, wrptr);
Avinash Patil42a028a2014-09-12 20:08:47 +05301356 dev_kfree_skb_any(skb_data);
1357 } else {
1358 skb_put(skb_data, rx_len);
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301359 mwifiex_dbg(adapter, DATA,
1360 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1361 card->rxbd_rdptr, wrptr, rx_len);
Avinash Patil42a028a2014-09-12 20:08:47 +05301362 skb_pull(skb_data, INTF_HEADER_LEN);
Avinash Patil6e251172014-09-12 20:08:59 +05301363 if (adapter->rx_work_enabled) {
Avinash Patil6e251172014-09-12 20:08:59 +05301364 skb_queue_tail(&adapter->rx_data_q, skb_data);
Avinash Patil6e251172014-09-12 20:08:59 +05301365 adapter->data_received = true;
1366 atomic_inc(&adapter->rx_pending);
1367 } else {
1368 mwifiex_handle_rx_packet(adapter, skb_data);
1369 }
Avinash Patil42a028a2014-09-12 20:08:47 +05301370 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001371
Avinash Patil62159942015-03-13 17:37:52 +05301372 skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
Mathias Krause5c87a552016-05-21 15:43:31 +02001373 GFP_KERNEL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001374 if (!skb_tmp) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301375 mwifiex_dbg(adapter, ERROR,
1376 "Unable to allocate skb.\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001377 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001378 }
1379
Avinash Patile7f767a2013-01-03 21:21:32 -08001380 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1381 MWIFIEX_RX_DATA_BUF_SIZE,
1382 PCI_DMA_FROMDEVICE))
1383 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001384
Aaron Durbindbccc922014-02-07 16:25:50 -08001385 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001386
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301387 mwifiex_dbg(adapter, INFO,
1388 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1389 skb_tmp, rd_index);
Avinash Patile7f767a2013-01-03 21:21:32 -08001390 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001391
1392 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001393 desc2 = card->rxbd_ring[rd_index];
Avinash Patilca8f2112013-02-08 18:18:09 -08001394 desc2->paddr = buf_pa;
1395 desc2->len = skb_tmp->len;
1396 desc2->frag_len = skb_tmp->len;
1397 desc2->offset = 0;
1398 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1399 } else {
1400 desc = card->rxbd_ring[rd_index];
1401 desc->paddr = buf_pa;
1402 desc->len = skb_tmp->len;
1403 desc->flags = 0;
1404 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001405
Avinash Patildd04e6a2013-02-08 18:18:06 -08001406 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001407 MWIFIEX_MAX_TXRX_BD) {
1408 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001409 reg->rx_rollover_ind) ^
1410 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001411 }
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301412 mwifiex_dbg(adapter, DATA,
1413 "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
1414 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001415
Avinash Patilca8f2112013-02-08 18:18:09 -08001416 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001417 /* Write the RX ring read pointer in to reg->rx_rdptr */
1418 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001419 card->rxbd_rdptr | tx_val)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301420 mwifiex_dbg(adapter, DATA,
1421 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001422 ret = -1;
1423 goto done;
1424 }
1425
1426 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001427 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301428 mwifiex_dbg(adapter, ERROR,
1429 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001430 ret = -1;
1431 goto done;
1432 }
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301433 mwifiex_dbg(adapter, DATA,
1434 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001435 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001436 }
1437
1438done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001439 return ret;
1440}
1441
1442/*
1443 * This function downloads the boot command to device
1444 */
1445static int
1446mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1447{
Avinash Patilfc331462013-01-03 21:21:30 -08001448 dma_addr_t buf_pa;
1449 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001450 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001451
Avinash Patilfc331462013-01-03 21:21:30 -08001452 if (!(skb->data && skb->len)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301453 mwifiex_dbg(adapter, ERROR,
1454 "Invalid parameter in %s <%p. len %d>\n",
1455 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001456 return -1;
1457 }
1458
Ujjal Roy3a968d72016-02-25 00:49:43 +05301459 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
Avinash Patilfc331462013-01-03 21:21:30 -08001460 return -1;
1461
Aaron Durbindbccc922014-02-07 16:25:50 -08001462 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001463
Avinash Patildd04e6a2013-02-08 18:18:06 -08001464 /* Write the lower 32bits of the physical address to low command
1465 * address scratch register
1466 */
1467 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301468 mwifiex_dbg(adapter, ERROR,
1469 "%s: failed to write download command to boot code.\n",
1470 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001471 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001472 return -1;
1473 }
1474
Avinash Patildd04e6a2013-02-08 18:18:06 -08001475 /* Write the upper 32bits of the physical address to high command
1476 * address scratch register
1477 */
1478 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001479 (u32)((u64)buf_pa >> 32))) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301480 mwifiex_dbg(adapter, ERROR,
1481 "%s: failed to write download command to boot code.\n",
1482 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001483 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001484 return -1;
1485 }
1486
Avinash Patildd04e6a2013-02-08 18:18:06 -08001487 /* Write the command length to cmd_size scratch register */
1488 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301489 mwifiex_dbg(adapter, ERROR,
1490 "%s: failed to write command len to cmd_size scratch reg\n",
1491 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001492 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001493 return -1;
1494 }
1495
1496 /* Ring the door bell */
1497 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1498 CPU_INTR_DOOR_BELL)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301499 mwifiex_dbg(adapter, ERROR,
1500 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001501 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001502 return -1;
1503 }
1504
1505 return 0;
1506}
1507
Avinash Patilc6d1d872013-01-03 21:21:29 -08001508/* This function init rx port in firmware which in turn enables to receive data
1509 * from device before transmitting any packet.
1510 */
1511static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1512{
1513 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001514 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001515 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001516
Avinash Patildd04e6a2013-02-08 18:18:06 -08001517 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001518 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1519 tx_wrap)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301520 mwifiex_dbg(adapter, ERROR,
1521 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001522 return -1;
1523 }
1524 return 0;
1525}
1526
1527/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001528 */
1529static int
1530mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1531{
1532 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001533 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001534 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001535 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1536 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001537
1538 if (!(skb->data && skb->len)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301539 mwifiex_dbg(adapter, ERROR,
1540 "Invalid parameter in %s <%p, %#x>\n",
1541 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001542 return -1;
1543 }
1544
1545 /* Make sure a command response buffer is available */
1546 if (!card->cmdrsp_buf) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301547 mwifiex_dbg(adapter, ERROR,
1548 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001549 return -EBUSY;
1550 }
1551
Avinash Patilfc331462013-01-03 21:21:30 -08001552 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1553 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001554
1555 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001556
1557 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1558 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1559
1560 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1561 return -1;
1562
1563 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001564
1565 /* To send a command, the driver will:
1566 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001567 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001568 2. Ring the door bell (i.e. set the door bell interrupt)
1569
1570 In response to door bell interrupt, the firmware will perform
1571 the DMA of the command packet (first header to obtain the total
1572 length and then rest of the command).
1573 */
1574
1575 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001576 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001577 /* Write the lower 32bits of the cmdrsp buffer physical
1578 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001579 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001580 (u32)cmdrsp_buf_pa)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301581 mwifiex_dbg(adapter, ERROR,
1582 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001583 ret = -1;
1584 goto done;
1585 }
1586 /* Write the upper 32bits of the cmdrsp buffer physical
1587 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001588 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001589 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301590 mwifiex_dbg(adapter, ERROR,
1591 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001592 ret = -1;
1593 goto done;
1594 }
1595 }
1596
Aaron Durbindbccc922014-02-07 16:25:50 -08001597 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001598 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1599 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1600 (u32)cmd_buf_pa)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301601 mwifiex_dbg(adapter, ERROR,
1602 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001603 ret = -1;
1604 goto done;
1605 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001606 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1607 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001608 (u32)((u64)cmd_buf_pa >> 32))) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301609 mwifiex_dbg(adapter, ERROR,
1610 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001611 ret = -1;
1612 goto done;
1613 }
1614
Avinash Patildd04e6a2013-02-08 18:18:06 -08001615 /* Write the command length to reg->cmd_size */
1616 if (mwifiex_write_reg(adapter, reg->cmd_size,
1617 card->cmd_buf->len)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301618 mwifiex_dbg(adapter, ERROR,
1619 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001620 ret = -1;
1621 goto done;
1622 }
1623
1624 /* Ring the door bell */
1625 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1626 CPU_INTR_DOOR_BELL)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301627 mwifiex_dbg(adapter, ERROR,
1628 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001629 ret = -1;
1630 goto done;
1631 }
1632
1633done:
1634 if (ret)
1635 adapter->cmd_sent = false;
1636
1637 return 0;
1638}
1639
1640/*
1641 * This function handles command complete interrupt
1642 */
1643static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1644{
1645 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001646 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001647 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001648 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001649 u16 rx_len;
1650 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001651
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301652 mwifiex_dbg(adapter, CMD,
1653 "info: Rx CMD Response\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001654
Aaron Durbindbccc922014-02-07 16:25:50 -08001655 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001656
Aaron Durbin189b3292014-02-07 16:25:51 -08001657 /* Unmap the command as a response has been received. */
1658 if (card->cmd_buf) {
1659 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1660 PCI_DMA_TODEVICE);
1661 card->cmd_buf = NULL;
1662 }
1663
Avinash Patilfc331462013-01-03 21:21:30 -08001664 pkt_len = *((__le16 *)skb->data);
1665 rx_len = le16_to_cpu(pkt_len);
Amitkumar Karwar2fd40d22016-07-15 19:07:05 +05301666 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patilfc331462013-01-03 21:21:30 -08001667 skb_trim(skb, rx_len);
1668 skb_pull(skb, INTF_HEADER_LEN);
1669
Amitkumar Karward930fae2011-10-11 17:41:21 -07001670 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001671 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001672 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1673 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001674 mwifiex_pcie_enable_host_int(adapter);
1675 if (mwifiex_write_reg(adapter,
1676 PCIE_CPU_INT_EVENT,
1677 CPU_INTR_SLEEP_CFM_DONE)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301678 mwifiex_dbg(adapter, ERROR,
1679 "Write register failed\n");
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001680 return -1;
1681 }
Avinash Patilc4bc9802014-03-18 22:19:17 -07001682 mwifiex_delay_for_sleep_cookie(adapter,
1683 MWIFIEX_MAX_DELAY_COUNT);
Avinash Patil52301a82013-02-12 14:38:32 -08001684 while (reg->sleep_cookie && (count++ < 10) &&
1685 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001686 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001687 } else {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301688 mwifiex_dbg(adapter, ERROR,
1689 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001690 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001691 memcpy(adapter->upld_buf, skb->data,
1692 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001693 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001694 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1695 PCI_DMA_FROMDEVICE))
1696 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001697 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001698 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001699 adapter->cmd_resp_received = true;
1700 /* Take the pointer and set it to CMD node and will
1701 return in the response complete callback */
1702 card->cmdrsp_buf = NULL;
1703
1704 /* Clear the cmd-rsp buffer address in scratch registers. This
1705 will prevent firmware from writing to the same response
1706 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001707 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301708 mwifiex_dbg(adapter, ERROR,
1709 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001710 return -1;
1711 }
1712 /* Write the upper 32bits of the cmdrsp buffer physical
1713 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001714 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301715 mwifiex_dbg(adapter, ERROR,
1716 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001717 return -1;
1718 }
1719 }
1720
1721 return 0;
1722}
1723
1724/*
1725 * Command Response processing complete handler
1726 */
1727static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1728 struct sk_buff *skb)
1729{
1730 struct pcie_service_card *card = adapter->card;
1731
1732 if (skb) {
1733 card->cmdrsp_buf = skb;
1734 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001735 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1736 PCI_DMA_FROMDEVICE))
1737 return -1;
1738 }
1739
Amitkumar Karward930fae2011-10-11 17:41:21 -07001740 return 0;
1741}
1742
1743/*
1744 * This function handles firmware event ready interrupt
1745 */
1746static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1747{
1748 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001749 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001750 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1751 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001752 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001753
1754 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1755 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001756
1757 if (adapter->event_received) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301758 mwifiex_dbg(adapter, EVENT,
1759 "info: Event being processed,\t"
1760 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001761 return 0;
1762 }
1763
1764 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301765 mwifiex_dbg(adapter, ERROR,
1766 "info: Invalid read pointer...\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001767 return -1;
1768 }
1769
1770 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001771 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301772 mwifiex_dbg(adapter, ERROR,
1773 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001774 return -1;
1775 }
1776
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301777 mwifiex_dbg(adapter, EVENT,
1778 "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
1779 card->evtbd_rdptr, wrptr);
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001780 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1781 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001782 ((wrptr & reg->evt_rollover_ind) ==
1783 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001784 struct sk_buff *skb_cmd;
1785 __le16 data_len = 0;
1786 u16 evt_len;
1787
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301788 mwifiex_dbg(adapter, INFO,
1789 "info: Read Index: %d\n", rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001790 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001791 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001792
Amitkumar Karward930fae2011-10-11 17:41:21 -07001793 /* Take the pointer and set it to event pointer in adapter
1794 and will return back after event handling callback */
1795 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001796 desc = card->evtbd_ring[rdptr];
1797 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001798
1799 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1800 adapter->event_cause = event;
1801 /* The first 4bytes will be the event transfer header
1802 len is 2 bytes followed by type which is 2 bytes */
1803 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1804 evt_len = le16_to_cpu(data_len);
Zhaoyang Liu868093a2015-05-12 00:48:19 +05301805 skb_trim(skb_cmd, evt_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001806 skb_pull(skb_cmd, INTF_HEADER_LEN);
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301807 mwifiex_dbg(adapter, EVENT,
1808 "info: Event length: %d\n", evt_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001809
1810 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1811 memcpy(adapter->event_body, skb_cmd->data +
1812 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1813 MWIFIEX_EVENT_HEADER_LEN);
1814
1815 adapter->event_received = true;
1816 adapter->event_skb = skb_cmd;
1817
1818 /* Do not update the event read pointer here, wait till the
1819 buffer is released. This is just to make things simpler,
1820 we need to find a better method of managing these buffers.
1821 */
Avinash Patil2703a662014-09-12 20:08:49 +05301822 } else {
1823 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1824 CPU_INTR_EVENT_DONE)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301825 mwifiex_dbg(adapter, ERROR,
1826 "Write register failed\n");
Avinash Patil2703a662014-09-12 20:08:49 +05301827 return -1;
1828 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001829 }
1830
1831 return 0;
1832}
1833
1834/*
1835 * Event processing complete handler
1836 */
1837static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1838 struct sk_buff *skb)
1839{
1840 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001841 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001842 int ret = 0;
1843 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1844 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001845 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001846
1847 if (!skb)
1848 return 0;
1849
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001850 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301851 mwifiex_dbg(adapter, ERROR,
1852 "event_complete: Invalid rdptr 0x%x\n",
1853 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001854 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001855 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001856
1857 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001858 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301859 mwifiex_dbg(adapter, ERROR,
1860 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001861 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001862 }
1863
1864 if (!card->evt_buf_list[rdptr]) {
1865 skb_push(skb, INTF_HEADER_LEN);
Amitkumar Karwar2728cec2015-07-22 04:53:45 -07001866 skb_put(skb, MAX_EVENT_SIZE - skb->len);
Avinash Patilfc331462013-01-03 21:21:30 -08001867 if (mwifiex_map_pci_memory(adapter, skb,
1868 MAX_EVENT_SIZE,
1869 PCI_DMA_FROMDEVICE))
1870 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001871 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001872 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001873 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001874 desc->len = (u16)skb->len;
1875 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001876 skb = NULL;
1877 } else {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301878 mwifiex_dbg(adapter, ERROR,
1879 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1880 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001881 }
1882
1883 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1884 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001885 reg->evt_rollover_ind) ^
1886 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001887 }
1888
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301889 mwifiex_dbg(adapter, EVENT,
1890 "info: Updated <Rd: 0x%x, Wr: 0x%x>",
1891 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001892
Avinash Patildd04e6a2013-02-08 18:18:06 -08001893 /* Write the event ring read pointer in to reg->evt_rdptr */
1894 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1895 card->evtbd_rdptr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301896 mwifiex_dbg(adapter, ERROR,
1897 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001898 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001899 }
1900
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301901 mwifiex_dbg(adapter, EVENT,
1902 "info: Check Events Again\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001903 ret = mwifiex_pcie_process_event_ready(adapter);
1904
1905 return ret;
1906}
1907
1908/*
1909 * This function downloads the firmware to the card.
1910 *
1911 * Firmware is downloaded to the card in blocks. Every block download
1912 * is tested for CRC errors, and retried a number of times before
1913 * returning failure.
1914 */
1915static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1916 struct mwifiex_fw_image *fw)
1917{
1918 int ret;
1919 u8 *firmware = fw->fw_buf;
1920 u32 firmware_len = fw->fw_len;
1921 u32 offset = 0;
1922 struct sk_buff *skb;
1923 u32 txlen, tx_blocks = 0, tries, len;
1924 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001925 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001926 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001927
1928 if (!firmware || !firmware_len) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301929 mwifiex_dbg(adapter, ERROR,
1930 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001931 return -1;
1932 }
1933
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301934 mwifiex_dbg(adapter, INFO,
1935 "info: Downloading FW image (%d bytes)\n",
1936 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001937
1938 if (mwifiex_pcie_disable_host_int(adapter)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301939 mwifiex_dbg(adapter, ERROR,
1940 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001941 return -1;
1942 }
1943
1944 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1945 if (!skb) {
1946 ret = -ENOMEM;
1947 goto done;
1948 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001949
1950 /* Perform firmware data transfer */
1951 do {
1952 u32 ireg_intr = 0;
1953
1954 /* More data? */
1955 if (offset >= firmware_len)
1956 break;
1957
1958 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001959 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001960 &len);
1961 if (ret) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301962 mwifiex_dbg(adapter, FATAL,
1963 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001964 goto done;
1965 }
1966 if (len)
1967 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001968 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001969 }
1970
1971 if (!len) {
1972 break;
1973 } else if (len > MWIFIEX_UPLD_SIZE) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301974 mwifiex_dbg(adapter, ERROR,
1975 "FW download failure @ %d, invalid length %d\n",
1976 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001977 ret = -1;
1978 goto done;
1979 }
1980
1981 txlen = len;
1982
1983 if (len & BIT(0)) {
1984 block_retry_cnt++;
1985 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301986 mwifiex_dbg(adapter, ERROR,
1987 "FW download failure @ %d, over max\t"
1988 "retry count\n", offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001989 ret = -1;
1990 goto done;
1991 }
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05301992 mwifiex_dbg(adapter, ERROR,
1993 "FW CRC error indicated by the\t"
1994 "helper: len = 0x%04X, txlen = %d\n",
1995 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001996 len &= ~BIT(0);
1997 /* Setting this to 0 to resend from same offset */
1998 txlen = 0;
1999 } else {
2000 block_retry_cnt = 0;
2001 /* Set blocksize to transfer - checking for
2002 last block */
2003 if (firmware_len - offset < txlen)
2004 txlen = firmware_len - offset;
2005
Avinash Patildd04e6a2013-02-08 18:18:06 -08002006 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
2007 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002008
2009 /* Copy payload to buffer */
2010 memmove(skb->data, &firmware[offset], txlen);
2011 }
2012
2013 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08002014 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002015
2016 /* Send the boot command to device */
2017 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302018 mwifiex_dbg(adapter, ERROR,
2019 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002020 ret = -1;
2021 goto done;
2022 }
Avinash Patilfc331462013-01-03 21:21:30 -08002023
Amitkumar Karward930fae2011-10-11 17:41:21 -07002024 /* Wait for the command done interrupt */
2025 do {
2026 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
2027 &ireg_intr)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302028 mwifiex_dbg(adapter, ERROR,
2029 "%s: Failed to read\t"
2030 "interrupt status during fw dnld.\n",
2031 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08002032 mwifiex_unmap_pci_memory(adapter, skb,
2033 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002034 ret = -1;
2035 goto done;
2036 }
2037 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
2038 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08002039
Aaron Durbindbccc922014-02-07 16:25:50 -08002040 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08002041
Amitkumar Karward930fae2011-10-11 17:41:21 -07002042 offset += txlen;
2043 } while (true);
2044
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302045 mwifiex_dbg(adapter, MSG,
2046 "info: FW download over, size %d bytes\n", offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002047
2048 ret = 0;
2049
2050done:
2051 dev_kfree_skb_any(skb);
2052 return ret;
2053}
2054
2055/*
2056 * This function checks the firmware status in card.
Amitkumar Karward930fae2011-10-11 17:41:21 -07002057 */
2058static int
2059mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
2060{
2061 int ret = 0;
chunfan chen2fd5c6e2016-01-06 23:40:47 -08002062 u32 firmware_stat;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002063 struct pcie_service_card *card = adapter->card;
2064 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002065 u32 tries;
2066
2067 /* Mask spurios interrupts */
2068 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002069 HOST_INTR_MASK)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302070 mwifiex_dbg(adapter, ERROR,
2071 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002072 return -1;
2073 }
2074
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302075 mwifiex_dbg(adapter, INFO,
2076 "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002077 if (mwifiex_write_reg(adapter, reg->drv_rdy,
2078 FIRMWARE_READY_PCIE)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302079 mwifiex_dbg(adapter, ERROR,
2080 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002081 return -1;
2082 }
2083
2084 /* Wait for firmware initialization event */
2085 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08002086 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002087 &firmware_stat))
2088 ret = -1;
2089 else
2090 ret = 0;
Stanislaw Gruszka09dd9ec2016-08-25 17:05:17 +02002091
2092 mwifiex_dbg(adapter, INFO, "Try %d if FW is ready <%d,%#x>",
2093 tries, ret, firmware_stat);
2094
Amitkumar Karward930fae2011-10-11 17:41:21 -07002095 if (ret)
2096 continue;
2097 if (firmware_stat == FIRMWARE_READY_PCIE) {
2098 ret = 0;
2099 break;
2100 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07002101 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002102 ret = -1;
2103 }
2104 }
2105
chunfan chen2fd5c6e2016-01-06 23:40:47 -08002106 return ret;
2107}
2108
2109/* This function checks if WLAN is the winner.
2110 */
2111static int
2112mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
2113{
2114 u32 winner = 0;
2115 int ret = 0;
2116 struct pcie_service_card *card = adapter->card;
2117 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2118
2119 if (mwifiex_read_reg(adapter, reg->fw_status, &winner)) {
2120 ret = -1;
2121 } else if (!winner) {
2122 mwifiex_dbg(adapter, INFO, "PCI-E is the winner\n");
2123 adapter->winner = 1;
2124 } else {
2125 mwifiex_dbg(adapter, ERROR,
Stanislaw Gruszkafd3fbb62016-08-25 17:05:16 +02002126 "PCI-E is not the winner <%#x>", winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002127 }
2128
2129 return ret;
2130}
2131
2132/*
2133 * This function reads the interrupt status from card.
2134 */
Xinming Hu99074fc2016-01-11 02:16:40 -08002135static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter,
2136 int msg_id)
Amitkumar Karward930fae2011-10-11 17:41:21 -07002137{
2138 u32 pcie_ireg;
2139 unsigned long flags;
Xinming Hu99074fc2016-01-11 02:16:40 -08002140 struct pcie_service_card *card = adapter->card;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002141
Shengzhen Li5781fc22016-07-01 18:26:52 +05302142 if (card->msi_enable) {
2143 spin_lock_irqsave(&adapter->int_lock, flags);
2144 adapter->int_status = 1;
2145 spin_unlock_irqrestore(&adapter->int_lock, flags);
2146 return;
2147 }
2148
Amitkumar Karward930fae2011-10-11 17:41:21 -07002149 if (!mwifiex_pcie_ok_to_access_hw(adapter))
2150 return;
2151
Xinming Hu99074fc2016-01-11 02:16:40 -08002152 if (card->msix_enable && msg_id >= 0) {
2153 pcie_ireg = BIT(msg_id);
2154 } else {
2155 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2156 &pcie_ireg)) {
2157 mwifiex_dbg(adapter, ERROR, "Read register failed\n");
2158 return;
2159 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002160
Xinming Hu99074fc2016-01-11 02:16:40 -08002161 if ((pcie_ireg == 0xFFFFFFFF) || !pcie_ireg)
2162 return;
2163
Amitkumar Karward930fae2011-10-11 17:41:21 -07002164
2165 mwifiex_pcie_disable_host_int(adapter);
2166
2167 /* Clear the pending interrupts */
2168 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2169 ~pcie_ireg)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302170 mwifiex_dbg(adapter, ERROR,
2171 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002172 return;
2173 }
Xinming Hu99074fc2016-01-11 02:16:40 -08002174 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002175
Xinming Hu99074fc2016-01-11 02:16:40 -08002176 if (!adapter->pps_uapsd_mode &&
2177 adapter->ps_state == PS_STATE_SLEEP &&
2178 mwifiex_pcie_ok_to_access_hw(adapter)) {
2179 /* Potentially for PCIe we could get other
2180 * interrupts like shared. Don't change power
2181 * state until cookie is set
2182 */
2183 adapter->ps_state = PS_STATE_AWAKE;
2184 adapter->pm_wakeup_fw_try = false;
2185 del_timer(&adapter->wakeup_timer);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002186 }
Shengzhen Lidc896b12016-01-12 05:43:16 -08002187
2188 spin_lock_irqsave(&adapter->int_lock, flags);
2189 adapter->int_status |= pcie_ireg;
2190 spin_unlock_irqrestore(&adapter->int_lock, flags);
2191 mwifiex_dbg(adapter, INTR, "ireg: 0x%08x\n", pcie_ireg);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002192}
2193
2194/*
2195 * Interrupt handler for PCIe root port
2196 *
2197 * This function reads the interrupt status from firmware and assigns
2198 * the main process in workqueue which will handle the interrupt.
2199 */
2200static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2201{
Xinming Hu99074fc2016-01-11 02:16:40 -08002202 struct mwifiex_msix_context *ctx = context;
2203 struct pci_dev *pdev = ctx->dev;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002204 struct pcie_service_card *card;
2205 struct mwifiex_adapter *adapter;
2206
2207 if (!pdev) {
Xinming Hu91442432015-12-31 06:24:14 -08002208 pr_err("info: %s: pdev is NULL\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002209 goto exit;
2210 }
2211
Jingoo Hanb2a31202013-09-09 14:26:51 +09002212 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002213 if (!card || !card->adapter) {
Xinming Hu91442432015-12-31 06:24:14 -08002214 pr_err("info: %s: card=%p adapter=%p\n", __func__, card,
2215 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002216 goto exit;
2217 }
2218 adapter = card->adapter;
2219
2220 if (adapter->surprise_removed)
2221 goto exit;
2222
Xinming Hu99074fc2016-01-11 02:16:40 -08002223 if (card->msix_enable)
2224 mwifiex_interrupt_status(adapter, ctx->msg_id);
2225 else
2226 mwifiex_interrupt_status(adapter, -1);
2227
Shengzhen Lib2713f62015-03-13 17:37:54 +05302228 mwifiex_queue_main_work(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002229
2230exit:
2231 return IRQ_HANDLED;
2232}
2233
2234/*
2235 * This function checks the current interrupt status.
2236 *
2237 * The following interrupts are checked and handled by this function -
2238 * - Data sent
2239 * - Command sent
2240 * - Command received
2241 * - Packets received
2242 * - Events received
2243 *
2244 * In case of Rx packets received, the packets are uploaded from card to
2245 * host and processed accordingly.
2246 */
Xinming Hu99074fc2016-01-11 02:16:40 -08002247static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -07002248{
2249 int ret;
Shengzhen Li5781fc22016-07-01 18:26:52 +05302250 u32 pcie_ireg = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002251 unsigned long flags;
Shengzhen Li5781fc22016-07-01 18:26:52 +05302252 struct pcie_service_card *card = adapter->card;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002253
2254 spin_lock_irqsave(&adapter->int_lock, flags);
Shengzhen Li5781fc22016-07-01 18:26:52 +05302255 if (!card->msi_enable) {
2256 /* Clear out unused interrupts */
2257 pcie_ireg = adapter->int_status;
2258 }
Avinash Patil659c4782013-01-03 21:21:28 -08002259 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002260 spin_unlock_irqrestore(&adapter->int_lock, flags);
2261
Shengzhen Li5781fc22016-07-01 18:26:52 +05302262 if (card->msi_enable) {
2263 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2264 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2265 &pcie_ireg)) {
2266 mwifiex_dbg(adapter, ERROR,
2267 "Read register failed\n");
2268 return -1;
2269 }
2270
2271 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2272 if (mwifiex_write_reg(adapter,
2273 PCIE_HOST_INT_STATUS,
2274 ~pcie_ireg)) {
2275 mwifiex_dbg(adapter, ERROR,
2276 "Write register failed\n");
2277 return -1;
2278 }
2279 if (!adapter->pps_uapsd_mode &&
2280 adapter->ps_state == PS_STATE_SLEEP) {
2281 adapter->ps_state = PS_STATE_AWAKE;
2282 adapter->pm_wakeup_fw_try = false;
2283 del_timer(&adapter->wakeup_timer);
2284 }
2285 }
2286 }
2287 }
Avinash Patil659c4782013-01-03 21:21:28 -08002288 while (pcie_ireg & HOST_INTR_MASK) {
2289 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2290 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302291 mwifiex_dbg(adapter, INTR,
2292 "info: TX DNLD Done\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08002293 ret = mwifiex_pcie_send_data_complete(adapter);
2294 if (ret)
2295 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002296 }
Avinash Patil659c4782013-01-03 21:21:28 -08002297 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2298 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302299 mwifiex_dbg(adapter, INTR,
2300 "info: Rx DATA\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002301 ret = mwifiex_pcie_process_recv_data(adapter);
2302 if (ret)
2303 return ret;
2304 }
Avinash Patil659c4782013-01-03 21:21:28 -08002305 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2306 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302307 mwifiex_dbg(adapter, INTR,
2308 "info: Rx EVENT\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002309 ret = mwifiex_pcie_process_event_ready(adapter);
2310 if (ret)
2311 return ret;
2312 }
2313
Avinash Patil659c4782013-01-03 21:21:28 -08002314 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2315 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002316 if (adapter->cmd_sent) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302317 mwifiex_dbg(adapter, INTR,
2318 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002319 adapter->cmd_sent = false;
2320 }
2321 /* Handle command response */
2322 ret = mwifiex_pcie_process_cmd_complete(adapter);
2323 if (ret)
2324 return ret;
2325 }
2326
Shengzhen Li5781fc22016-07-01 18:26:52 +05302327 if (card->msi_enable) {
2328 spin_lock_irqsave(&adapter->int_lock, flags);
2329 adapter->int_status = 0;
2330 spin_unlock_irqrestore(&adapter->int_lock, flags);
2331 }
2332
Amitkumar Karward930fae2011-10-11 17:41:21 -07002333 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2334 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2335 &pcie_ireg)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302336 mwifiex_dbg(adapter, ERROR,
2337 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002338 return -1;
2339 }
2340
2341 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2342 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002343 PCIE_HOST_INT_STATUS,
2344 ~pcie_ireg)) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302345 mwifiex_dbg(adapter, ERROR,
2346 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002347 return -1;
2348 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002349 }
2350
2351 }
Amitkumar Karwar51495282016-07-15 19:07:04 +05302352 if (!card->msi_enable) {
2353 spin_lock_irqsave(&adapter->int_lock, flags);
2354 pcie_ireg |= adapter->int_status;
2355 adapter->int_status = 0;
2356 spin_unlock_irqrestore(&adapter->int_lock, flags);
2357 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002358 }
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302359 mwifiex_dbg(adapter, INTR,
2360 "info: cmd_sent=%d data_sent=%d\n",
2361 adapter->cmd_sent, adapter->data_sent);
Shengzhen Li5781fc22016-07-01 18:26:52 +05302362 if (!card->msi_enable && adapter->ps_state != PS_STATE_SLEEP)
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002363 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002364
2365 return 0;
2366}
2367
Xinming Hu99074fc2016-01-11 02:16:40 -08002368static int mwifiex_process_msix_int(struct mwifiex_adapter *adapter)
2369{
2370 int ret;
2371 u32 pcie_ireg;
2372 unsigned long flags;
2373
2374 spin_lock_irqsave(&adapter->int_lock, flags);
2375 /* Clear out unused interrupts */
2376 pcie_ireg = adapter->int_status;
2377 adapter->int_status = 0;
2378 spin_unlock_irqrestore(&adapter->int_lock, flags);
2379
2380 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2381 mwifiex_dbg(adapter, INTR,
2382 "info: TX DNLD Done\n");
2383 ret = mwifiex_pcie_send_data_complete(adapter);
2384 if (ret)
2385 return ret;
2386 }
2387 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2388 mwifiex_dbg(adapter, INTR,
2389 "info: Rx DATA\n");
2390 ret = mwifiex_pcie_process_recv_data(adapter);
2391 if (ret)
2392 return ret;
2393 }
2394 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2395 mwifiex_dbg(adapter, INTR,
2396 "info: Rx EVENT\n");
2397 ret = mwifiex_pcie_process_event_ready(adapter);
2398 if (ret)
2399 return ret;
2400 }
2401
2402 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2403 if (adapter->cmd_sent) {
2404 mwifiex_dbg(adapter, INTR,
2405 "info: CMD sent Interrupt\n");
2406 adapter->cmd_sent = false;
2407 }
2408 /* Handle command response */
2409 ret = mwifiex_pcie_process_cmd_complete(adapter);
2410 if (ret)
2411 return ret;
2412 }
2413
2414 mwifiex_dbg(adapter, INTR,
2415 "info: cmd_sent=%d data_sent=%d\n",
2416 adapter->cmd_sent, adapter->data_sent);
2417
2418 return 0;
2419}
2420
2421static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2422{
2423 struct pcie_service_card *card = adapter->card;
2424
2425 if (card->msix_enable)
2426 return mwifiex_process_msix_int(adapter);
2427 else
2428 return mwifiex_process_pcie_int(adapter);
2429}
2430
Amitkumar Karward930fae2011-10-11 17:41:21 -07002431/*
2432 * This function downloads data from driver to card.
2433 *
2434 * Both commands and data packets are transferred to the card by this
2435 * function.
2436 *
2437 * This function adds the PCIE specific header to the front of the buffer
2438 * before transferring. The header contains the length of the packet and
2439 * the type. The firmware handles the packets based upon this set type.
2440 */
2441static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2442 struct sk_buff *skb,
2443 struct mwifiex_tx_param *tx_param)
2444{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002445 if (!skb) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302446 mwifiex_dbg(adapter, ERROR,
2447 "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002448 return -1;
2449 }
2450
2451 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002452 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002453 else if (type == MWIFIEX_TYPE_CMD)
2454 return mwifiex_pcie_send_cmd(adapter, skb);
2455
2456 return 0;
2457}
2458
Xinming Hu46469682016-04-05 01:04:40 -07002459/* Function to dump PCIE scratch registers in case of FW crash
2460 */
2461static int
2462mwifiex_pcie_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
2463{
2464 char *p = drv_buf;
2465 char buf[256], *ptr;
2466 int i;
2467 u32 value;
2468 struct pcie_service_card *card = adapter->card;
2469 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2470 int pcie_scratch_reg[] = {PCIE_SCRATCH_12_REG,
2471 PCIE_SCRATCH_13_REG,
2472 PCIE_SCRATCH_14_REG};
2473
2474 if (!p)
2475 return 0;
2476
2477 mwifiex_dbg(adapter, MSG, "PCIE register dump start\n");
2478
2479 if (mwifiex_read_reg(adapter, reg->fw_status, &value)) {
2480 mwifiex_dbg(adapter, ERROR, "failed to read firmware status");
2481 return 0;
2482 }
2483
2484 ptr = buf;
2485 mwifiex_dbg(adapter, MSG, "pcie scratch register:");
2486 for (i = 0; i < ARRAY_SIZE(pcie_scratch_reg); i++) {
2487 mwifiex_read_reg(adapter, pcie_scratch_reg[i], &value);
2488 ptr += sprintf(ptr, "reg:0x%x, value=0x%x\n",
2489 pcie_scratch_reg[i], value);
2490 }
2491
2492 mwifiex_dbg(adapter, MSG, "%s\n", buf);
2493 p += sprintf(p, "%s\n", buf);
2494
2495 mwifiex_dbg(adapter, MSG, "PCIE register dump end\n");
2496
2497 return p - drv_buf;
2498}
2499
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002500/* This function read/write firmware */
2501static enum rdwr_status
2502mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2503{
2504 int ret, tries;
2505 u8 ctrl_data;
Xinming Hu01724042016-02-02 22:05:04 -08002506 u32 fw_status;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002507 struct pcie_service_card *card = adapter->card;
2508 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2509
Xinming Hu01724042016-02-02 22:05:04 -08002510 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status))
2511 return RDWR_STATUS_FAILURE;
2512
Xinming Hu50632092016-02-02 22:05:06 -08002513 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2514 reg->fw_dump_host_ready);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002515 if (ret) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302516 mwifiex_dbg(adapter, ERROR,
2517 "PCIE write err\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002518 return RDWR_STATUS_FAILURE;
2519 }
2520
2521 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2522 mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
2523 if (ctrl_data == FW_DUMP_DONE)
2524 return RDWR_STATUS_SUCCESS;
2525 if (doneflag && ctrl_data == doneflag)
2526 return RDWR_STATUS_DONE;
Xinming Hu50632092016-02-02 22:05:06 -08002527 if (ctrl_data != reg->fw_dump_host_ready) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302528 mwifiex_dbg(adapter, WARN,
2529 "The ctrl reg was changed, re-try again!\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002530 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
Xinming Hu50632092016-02-02 22:05:06 -08002531 reg->fw_dump_host_ready);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002532 if (ret) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302533 mwifiex_dbg(adapter, ERROR,
2534 "PCIE write err\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002535 return RDWR_STATUS_FAILURE;
2536 }
2537 }
2538 usleep_range(100, 200);
2539 }
2540
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302541 mwifiex_dbg(adapter, ERROR, "Fail to pull ctrl_data\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002542 return RDWR_STATUS_FAILURE;
2543}
2544
2545/* This function dump firmware memory to file */
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002546static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002547{
2548 struct pcie_service_card *card = adapter->card;
2549 const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
2550 unsigned int reg, reg_start, reg_end;
Xinming Hu11e70822016-02-02 22:05:09 -08002551 u8 *dbg_ptr, *end_ptr, *tmp_ptr, fw_dump_num, dump_num;
Xinming Hu56486022016-02-02 22:05:07 -08002552 u8 idx, i, read_reg, doneflag = 0;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002553 enum rdwr_status stat;
2554 u32 memory_size;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002555 int ret;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002556
Avinash Patilb4e8aeb2015-02-11 23:12:26 +05302557 if (!card->pcie.can_dump_fw)
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002558 return;
2559
Xinming Hu50632092016-02-02 22:05:06 -08002560 for (idx = 0; idx < adapter->num_mem_types; idx++) {
2561 struct memory_type_mapping *entry =
2562 &adapter->mem_type_mapping_tbl[idx];
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002563
2564 if (entry->mem_ptr) {
2565 vfree(entry->mem_ptr);
2566 entry->mem_ptr = NULL;
2567 }
2568 entry->mem_size = 0;
2569 }
2570
Amitkumar Karwar03f0f7c2016-02-02 22:05:08 -08002571 mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002572
2573 /* Read the number of the memories which will dump */
2574 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2575 if (stat == RDWR_STATUS_FAILURE)
Amitkumar Karwar57670ee2015-05-26 06:34:32 -07002576 return;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002577
2578 reg = creg->fw_dump_start;
Xinming Hu11e70822016-02-02 22:05:09 -08002579 mwifiex_read_reg_byte(adapter, reg, &fw_dump_num);
2580
2581 /* W8997 chipset firmware dump will be restore in single region*/
2582 if (fw_dump_num == 0)
2583 dump_num = 1;
2584 else
2585 dump_num = fw_dump_num;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002586
2587 /* Read the length of every memory which will dump */
2588 for (idx = 0; idx < dump_num; idx++) {
Xinming Hu50632092016-02-02 22:05:06 -08002589 struct memory_type_mapping *entry =
2590 &adapter->mem_type_mapping_tbl[idx];
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002591 memory_size = 0;
Xinming Hu11e70822016-02-02 22:05:09 -08002592 if (fw_dump_num != 0) {
2593 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2594 if (stat == RDWR_STATUS_FAILURE)
2595 return;
2596
2597 reg = creg->fw_dump_start;
2598 for (i = 0; i < 4; i++) {
2599 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2600 memory_size |= (read_reg << (i * 8));
Dan Carpenterccf5fa42016-02-09 14:15:36 +03002601 reg++;
Xinming Hu11e70822016-02-02 22:05:09 -08002602 }
2603 } else {
2604 memory_size = MWIFIEX_FW_DUMP_MAX_MEMSIZE;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002605 }
2606
2607 if (memory_size == 0) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302608 mwifiex_dbg(adapter, MSG, "Firmware dump Finished!\n");
Amitkumar Karwar7e174832014-09-18 07:18:50 -04002609 ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
Xinming Hu50632092016-02-02 22:05:06 -08002610 creg->fw_dump_read_done);
Amitkumar Karwar7e174832014-09-18 07:18:50 -04002611 if (ret) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302612 mwifiex_dbg(adapter, ERROR, "PCIE write err\n");
Amitkumar Karwar57670ee2015-05-26 06:34:32 -07002613 return;
Amitkumar Karwar7e174832014-09-18 07:18:50 -04002614 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002615 break;
2616 }
2617
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302618 mwifiex_dbg(adapter, DUMP,
2619 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002620 entry->mem_ptr = vmalloc(memory_size + 1);
2621 entry->mem_size = memory_size;
2622 if (!entry->mem_ptr) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302623 mwifiex_dbg(adapter, ERROR,
2624 "Vmalloc %s failed\n", entry->mem_name);
Amitkumar Karwar57670ee2015-05-26 06:34:32 -07002625 return;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002626 }
2627 dbg_ptr = entry->mem_ptr;
2628 end_ptr = dbg_ptr + memory_size;
2629
2630 doneflag = entry->done_flag;
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302631 mwifiex_dbg(adapter, DUMP, "Start %s output, please wait...\n",
2632 entry->mem_name);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002633
2634 do {
2635 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2636 if (RDWR_STATUS_FAILURE == stat)
Amitkumar Karwar57670ee2015-05-26 06:34:32 -07002637 return;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002638
2639 reg_start = creg->fw_dump_start;
2640 reg_end = creg->fw_dump_end;
2641 for (reg = reg_start; reg <= reg_end; reg++) {
2642 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
Amitkumar Karwar24716872014-09-18 08:04:01 -04002643 if (dbg_ptr < end_ptr) {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002644 dbg_ptr++;
Xinming Hu56486022016-02-02 22:05:07 -08002645 continue;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002646 }
Xinming Hu56486022016-02-02 22:05:07 -08002647 mwifiex_dbg(adapter, ERROR,
2648 "pre-allocated buf not enough\n");
2649 tmp_ptr =
2650 vzalloc(memory_size + MWIFIEX_SIZE_4K);
2651 if (!tmp_ptr)
2652 return;
2653 memcpy(tmp_ptr, entry->mem_ptr, memory_size);
2654 vfree(entry->mem_ptr);
2655 entry->mem_ptr = tmp_ptr;
2656 tmp_ptr = NULL;
2657 dbg_ptr = entry->mem_ptr + memory_size;
2658 memory_size += MWIFIEX_SIZE_4K;
2659 end_ptr = entry->mem_ptr + memory_size;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002660 }
2661
2662 if (stat != RDWR_STATUS_DONE)
2663 continue;
2664
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302665 mwifiex_dbg(adapter, DUMP,
2666 "%s done: size=0x%tx\n",
2667 entry->mem_name, dbg_ptr - entry->mem_ptr);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002668 break;
2669 } while (true);
2670 }
Amitkumar Karwar03f0f7c2016-02-02 22:05:08 -08002671 mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002672}
2673
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002674static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
2675{
2676 mwifiex_drv_info_dump(adapter);
2677 mwifiex_pcie_fw_dump(adapter);
Amitkumar Karwar57670ee2015-05-26 06:34:32 -07002678 mwifiex_upload_device_dump(adapter);
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002679}
2680
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002681static unsigned long iface_work_flags;
2682static struct mwifiex_adapter *save_adapter;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002683static void mwifiex_pcie_work(struct work_struct *work)
2684{
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002685 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002686 &iface_work_flags))
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002687 mwifiex_pcie_device_dump_work(save_adapter);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002688}
2689
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002690static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002691/* This function dumps FW information */
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002692static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002693{
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002694 save_adapter = adapter;
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002695 if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002696 return;
2697
Amitkumar Karwarfc697152015-05-26 06:34:31 -07002698 set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002699
Maithili Hinge2f5872b2015-03-22 23:01:25 -07002700 schedule_work(&pcie_work);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002701}
2702
Amitkumar Karward930fae2011-10-11 17:41:21 -07002703/*
2704 * This function initializes the PCI-E host memory space, WCB rings, etc.
2705 *
2706 * The following initializations steps are followed -
2707 * - Allocate TXBD ring buffers
2708 * - Allocate RXBD ring buffers
2709 * - Allocate event BD ring buffers
2710 * - Allocate command response ring buffer
2711 * - Allocate sleep cookie buffer
2712 */
2713static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2714{
2715 struct pcie_service_card *card = adapter->card;
2716 int ret;
2717 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002718 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002719
2720 pci_set_drvdata(pdev, card);
2721
2722 ret = pci_enable_device(pdev);
2723 if (ret)
2724 goto err_enable_dev;
2725
2726 pci_set_master(pdev);
2727
Xinming Hufdb1e282015-12-31 06:24:12 -08002728 pr_notice("try set_consistent_dma_mask(32)\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002729 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2730 if (ret) {
Xinming Hufdb1e282015-12-31 06:24:12 -08002731 pr_err("set_dma_mask(32) failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002732 goto err_set_dma_mask;
2733 }
2734
2735 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2736 if (ret) {
Xinming Hufdb1e282015-12-31 06:24:12 -08002737 pr_err("set_consistent_dma_mask(64) failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002738 goto err_set_dma_mask;
2739 }
2740
2741 ret = pci_request_region(pdev, 0, DRV_NAME);
2742 if (ret) {
Xinming Hufdb1e282015-12-31 06:24:12 -08002743 pr_err("req_reg(0) error\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002744 goto err_req_region0;
2745 }
2746 card->pci_mmap = pci_iomap(pdev, 0, 0);
2747 if (!card->pci_mmap) {
Xinming Hufdb1e282015-12-31 06:24:12 -08002748 pr_err("iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002749 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002750 goto err_iomap0;
2751 }
2752 ret = pci_request_region(pdev, 2, DRV_NAME);
2753 if (ret) {
Xinming Hufdb1e282015-12-31 06:24:12 -08002754 pr_err("req_reg(2) error\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002755 goto err_req_region2;
2756 }
2757 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2758 if (!card->pci_mmap1) {
Xinming Hufdb1e282015-12-31 06:24:12 -08002759 pr_err("iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002760 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002761 goto err_iomap2;
2762 }
2763
Xinming Hufdb1e282015-12-31 06:24:12 -08002764 pr_notice("PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2765 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002766
2767 card->cmdrsp_buf = NULL;
2768 ret = mwifiex_pcie_create_txbd_ring(adapter);
2769 if (ret)
2770 goto err_cre_txbd;
2771 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2772 if (ret)
2773 goto err_cre_rxbd;
2774 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2775 if (ret)
2776 goto err_cre_evtbd;
2777 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2778 if (ret)
2779 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002780 if (reg->sleep_cookie) {
2781 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2782 if (ret)
2783 goto err_alloc_cookie;
2784 } else {
2785 card->sleep_cookie_vbase = NULL;
2786 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002787 return ret;
2788
2789err_alloc_cookie:
2790 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2791err_alloc_cmdbuf:
2792 mwifiex_pcie_delete_evtbd_ring(adapter);
2793err_cre_evtbd:
2794 mwifiex_pcie_delete_rxbd_ring(adapter);
2795err_cre_rxbd:
2796 mwifiex_pcie_delete_txbd_ring(adapter);
2797err_cre_txbd:
2798 pci_iounmap(pdev, card->pci_mmap1);
2799err_iomap2:
2800 pci_release_region(pdev, 2);
2801err_req_region2:
2802 pci_iounmap(pdev, card->pci_mmap);
2803err_iomap0:
2804 pci_release_region(pdev, 0);
2805err_req_region0:
2806err_set_dma_mask:
2807 pci_disable_device(pdev);
2808err_enable_dev:
2809 pci_set_drvdata(pdev, NULL);
2810 return ret;
2811}
2812
2813/*
2814 * This function cleans up the allocated card buffers.
2815 *
2816 * The following are freed by this function -
2817 * - TXBD ring buffers
2818 * - RXBD ring buffers
2819 * - Event BD ring buffers
2820 * - Command response ring buffer
2821 * - Sleep cookie buffer
2822 */
2823static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2824{
2825 struct pcie_service_card *card = adapter->card;
2826 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002827 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002828
Amitkumar Karward930fae2011-10-11 17:41:21 -07002829 if (user_rmmod) {
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302830 mwifiex_dbg(adapter, INFO,
2831 "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002832 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Zhaoyang Liuacebe8c2015-05-12 00:48:20 +05302833 mwifiex_dbg(adapter, ERROR,
2834 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002835 }
2836
2837 if (pdev) {
2838 pci_iounmap(pdev, card->pci_mmap);
2839 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002840 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002841 pci_release_region(pdev, 2);
2842 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002843 pci_set_drvdata(pdev, NULL);
2844 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002845 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002846}
2847
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002848static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
2849{
Xinming Hu99074fc2016-01-11 02:16:40 -08002850 int ret, i, j;
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002851 struct pcie_service_card *card = adapter->card;
2852 struct pci_dev *pdev = card->dev;
2853
Xinming Hu99074fc2016-01-11 02:16:40 -08002854 if (card->pcie.reg->msix_support) {
2855 for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
2856 card->msix_entries[i].entry = i;
2857 ret = pci_enable_msix_exact(pdev, card->msix_entries,
2858 MWIFIEX_NUM_MSIX_VECTORS);
2859 if (!ret) {
2860 for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++) {
2861 card->msix_ctx[i].dev = pdev;
2862 card->msix_ctx[i].msg_id = i;
2863
2864 ret = request_irq(card->msix_entries[i].vector,
2865 mwifiex_pcie_interrupt, 0,
2866 "MWIFIEX_PCIE_MSIX",
2867 &card->msix_ctx[i]);
2868 if (ret)
2869 break;
2870 }
2871
2872 if (ret) {
2873 mwifiex_dbg(adapter, INFO, "request_irq fail: %d\n",
2874 ret);
2875 for (j = 0; j < i; j++)
2876 free_irq(card->msix_entries[j].vector,
2877 &card->msix_ctx[i]);
2878 pci_disable_msix(pdev);
2879 } else {
2880 mwifiex_dbg(adapter, MSG, "MSIx enabled!");
2881 card->msix_enable = 1;
2882 return 0;
2883 }
2884 }
2885 }
2886
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002887 if (pci_enable_msi(pdev) != 0)
2888 pci_disable_msi(pdev);
2889 else
2890 card->msi_enable = 1;
2891
2892 mwifiex_dbg(adapter, INFO, "msi_enable = %d\n", card->msi_enable);
2893
Xinming Hu99074fc2016-01-11 02:16:40 -08002894 card->share_irq_ctx.dev = pdev;
2895 card->share_irq_ctx.msg_id = -1;
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002896 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
Xinming Hu99074fc2016-01-11 02:16:40 -08002897 "MRVL_PCIE", &card->share_irq_ctx);
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002898 if (ret) {
2899 pr_err("request_irq failed: ret=%d\n", ret);
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002900 return -1;
2901 }
2902
2903 return 0;
2904}
2905
Amitkumar Karward930fae2011-10-11 17:41:21 -07002906/*
Julia Lawall47ce90f2016-05-17 16:38:46 +02002907 * This function gets the firmware name for downloading by revision id
Shengzhen Lia362e162016-04-05 01:04:36 -07002908 *
2909 * Read revision id register to get revision id
2910 */
2911static void mwifiex_pcie_get_fw_name(struct mwifiex_adapter *adapter)
2912{
2913 int revision_id = 0;
Amitkumar Karwar75696fe2016-07-29 16:08:51 +05302914 int version, magic;
Shengzhen Lia362e162016-04-05 01:04:36 -07002915 struct pcie_service_card *card = adapter->card;
2916
2917 switch (card->dev->device) {
2918 case PCIE_DEVICE_ID_MARVELL_88W8766P:
2919 strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME);
2920 break;
2921 case PCIE_DEVICE_ID_MARVELL_88W8897:
2922 mwifiex_write_reg(adapter, 0x0c58, 0x80c00000);
2923 mwifiex_read_reg(adapter, 0x0c58, &revision_id);
2924 revision_id &= 0xff00;
2925 switch (revision_id) {
2926 case PCIE8897_A0:
2927 strcpy(adapter->fw_name, PCIE8897_A0_FW_NAME);
2928 break;
2929 case PCIE8897_B0:
2930 strcpy(adapter->fw_name, PCIE8897_B0_FW_NAME);
2931 break;
2932 default:
Shengzhen Lib9db3972016-04-11 07:52:39 -07002933 strcpy(adapter->fw_name, PCIE8897_DEFAULT_FW_NAME);
2934
Shengzhen Lia362e162016-04-05 01:04:36 -07002935 break;
2936 }
Amitkumar Karwarc865a702016-04-11 07:52:37 -07002937 break;
Shengzhen Lia362e162016-04-05 01:04:36 -07002938 case PCIE_DEVICE_ID_MARVELL_88W8997:
Amitkumar Karwar75696fe2016-07-29 16:08:51 +05302939 mwifiex_read_reg(adapter, 0x8, &revision_id);
Shengzhen Lie87650b2016-04-11 07:52:38 -07002940 mwifiex_read_reg(adapter, 0x0cd0, &version);
Amitkumar Karwar75696fe2016-07-29 16:08:51 +05302941 mwifiex_read_reg(adapter, 0x0cd4, &magic);
2942 revision_id &= 0xff;
Shengzhen Lie87650b2016-04-11 07:52:38 -07002943 version &= 0x7;
Amitkumar Karwar75696fe2016-07-29 16:08:51 +05302944 magic &= 0xff;
2945 if (revision_id == PCIE8997_A1 &&
2946 magic == CHIP_MAGIC_VALUE &&
2947 version == CHIP_VER_PCIEUART)
2948 strcpy(adapter->fw_name, PCIEUART8997_FW_NAME_V4);
2949 else
2950 strcpy(adapter->fw_name, PCIEUSB8997_FW_NAME_V4);
2951 break;
Shengzhen Lia362e162016-04-05 01:04:36 -07002952 default:
2953 break;
2954 }
2955}
2956
2957/*
Amitkumar Karward930fae2011-10-11 17:41:21 -07002958 * This function registers the PCIE device.
2959 *
2960 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2961 */
2962static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2963{
Amitkumar Karward930fae2011-10-11 17:41:21 -07002964 struct pcie_service_card *card = adapter->card;
2965 struct pci_dev *pdev = card->dev;
2966
2967 /* save adapter pointer in card */
2968 card->adapter = adapter;
Xinming Hufdb1e282015-12-31 06:24:12 -08002969 adapter->dev = &pdev->dev;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002970
Avinash Patil7be0f5b2015-12-16 04:21:45 -08002971 if (mwifiex_pcie_request_irq(adapter))
Amitkumar Karward930fae2011-10-11 17:41:21 -07002972 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002973
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002974 adapter->tx_buf_size = card->pcie.tx_buf_size;
Xinming Hu50632092016-02-02 22:05:06 -08002975 adapter->mem_type_mapping_tbl = card->pcie.mem_type_mapping_tbl;
2976 adapter->num_mem_types = card->pcie.num_mem_types;
Avinash Patil1fe192d2015-01-23 17:09:19 +05302977 adapter->ext_scan = card->pcie.can_ext_scan;
Shengzhen Lia362e162016-04-05 01:04:36 -07002978 mwifiex_pcie_get_fw_name(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002979
2980 return 0;
2981}
2982
2983/*
2984 * This function unregisters the PCIE device.
2985 *
2986 * The PCIE IRQ is released, the function is disabled and driver
2987 * data is set to null.
2988 */
2989static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2990{
2991 struct pcie_service_card *card = adapter->card;
Heinrich Schuchardt141bcf02016-05-18 01:16:01 +02002992 struct pci_dev *pdev;
Xinming Hu99074fc2016-01-11 02:16:40 -08002993 int i;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002994
2995 if (card) {
Heinrich Schuchardt141bcf02016-05-18 01:16:01 +02002996 pdev = card->dev;
Xinming Hu99074fc2016-01-11 02:16:40 -08002997 if (card->msix_enable) {
2998 for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
2999 synchronize_irq(card->msix_entries[i].vector);
3000
3001 for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++)
3002 free_irq(card->msix_entries[i].vector,
3003 &card->msix_ctx[i]);
3004
3005 card->msix_enable = 0;
3006 pci_disable_msix(pdev);
3007 } else {
3008 mwifiex_dbg(adapter, INFO,
3009 "%s(): calling free_irq()\n", __func__);
3010 free_irq(card->dev->irq, &card->share_irq_ctx);
3011
3012 if (card->msi_enable)
3013 pci_disable_msi(pdev);
3014 }
Amitkumar Karwar4c5dae52016-07-26 19:31:44 +05303015 }
3016}
Avinash Patilfc331462013-01-03 21:21:30 -08003017
Amitkumar Karwar4c5dae52016-07-26 19:31:44 +05303018/* This function initializes the PCI-E host memory space, WCB rings, etc.
3019 *
3020 * The following initializations steps are followed -
3021 * - Allocate TXBD ring buffers
3022 * - Allocate RXBD ring buffers
3023 * - Allocate event BD ring buffers
3024 * - Allocate command response ring buffer
3025 * - Allocate sleep cookie buffer
3026 * Part of mwifiex_pcie_init(), not reset the PCIE registers
3027 */
3028static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
3029{
3030 struct pcie_service_card *card = adapter->card;
3031 int ret;
3032 struct pci_dev *pdev = card->dev;
3033 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
3034
3035 card->cmdrsp_buf = NULL;
3036 ret = mwifiex_pcie_create_txbd_ring(adapter);
3037 if (ret) {
3038 mwifiex_dbg(adapter, ERROR, "Failed to create txbd ring\n");
3039 goto err_cre_txbd;
3040 }
3041
3042 ret = mwifiex_pcie_create_rxbd_ring(adapter);
3043 if (ret) {
3044 mwifiex_dbg(adapter, ERROR, "Failed to create rxbd ring\n");
3045 goto err_cre_rxbd;
3046 }
3047
3048 ret = mwifiex_pcie_create_evtbd_ring(adapter);
3049 if (ret) {
3050 mwifiex_dbg(adapter, ERROR, "Failed to create evtbd ring\n");
3051 goto err_cre_evtbd;
3052 }
3053
3054 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
3055 if (ret) {
3056 mwifiex_dbg(adapter, ERROR, "Failed to allocate cmdbuf buffer\n");
3057 goto err_alloc_cmdbuf;
3058 }
3059
3060 if (reg->sleep_cookie) {
3061 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
3062 if (ret) {
3063 mwifiex_dbg(adapter, ERROR, "Failed to allocate sleep_cookie buffer\n");
3064 goto err_alloc_cookie;
3065 }
3066 } else {
3067 card->sleep_cookie_vbase = NULL;
3068 }
3069 return;
3070
3071err_alloc_cookie:
3072 mwifiex_pcie_delete_cmdrsp_buf(adapter);
3073err_alloc_cmdbuf:
3074 mwifiex_pcie_delete_evtbd_ring(adapter);
3075err_cre_evtbd:
3076 mwifiex_pcie_delete_rxbd_ring(adapter);
3077err_cre_rxbd:
3078 mwifiex_pcie_delete_txbd_ring(adapter);
3079err_cre_txbd:
3080 pci_iounmap(pdev, card->pci_mmap1);
3081}
3082
3083/* This function cleans up the PCI-E host memory space.
3084 * Some code is extracted from mwifiex_unregister_dev()
3085 *
3086 */
3087static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
3088{
3089 struct pcie_service_card *card = adapter->card;
3090 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
3091
3092 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
3093 mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n");
3094
3095 adapter->seq_num = 0;
3096 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
3097
3098 if (card) {
Avinash Patil52301a82013-02-12 14:38:32 -08003099 if (reg->sleep_cookie)
3100 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
3101
Avinash Patilfc331462013-01-03 21:21:30 -08003102 mwifiex_pcie_delete_cmdrsp_buf(adapter);
3103 mwifiex_pcie_delete_evtbd_ring(adapter);
3104 mwifiex_pcie_delete_rxbd_ring(adapter);
3105 mwifiex_pcie_delete_txbd_ring(adapter);
3106 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07003107 }
Amitkumar Karwar4c5dae52016-07-26 19:31:44 +05303108
3109 return;
Amitkumar Karward930fae2011-10-11 17:41:21 -07003110}
3111
3112static struct mwifiex_if_ops pcie_ops = {
3113 .init_if = mwifiex_pcie_init,
3114 .cleanup_if = mwifiex_pcie_cleanup,
3115 .check_fw_status = mwifiex_check_fw_status,
chunfan chen2fd5c6e2016-01-06 23:40:47 -08003116 .check_winner_status = mwifiex_check_winner_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07003117 .prog_fw = mwifiex_prog_fw_w_helper,
3118 .register_dev = mwifiex_register_dev,
3119 .unregister_dev = mwifiex_unregister_dev,
3120 .enable_int = mwifiex_pcie_enable_host_int,
Brian Norrisd41376c2016-06-30 15:21:02 -07003121 .disable_int = mwifiex_pcie_disable_host_int_noerr,
Amitkumar Karward930fae2011-10-11 17:41:21 -07003122 .process_int_status = mwifiex_process_int_status,
3123 .host_to_card = mwifiex_pcie_host_to_card,
3124 .wakeup = mwifiex_pm_wakeup_card,
3125 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
3126
3127 /* PCIE specific */
3128 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
3129 .event_complete = mwifiex_pcie_event_complete,
3130 .update_mp_end_port = NULL,
3131 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08003132 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08003133 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Xinming Hu46469682016-04-05 01:04:40 -07003134 .reg_dump = mwifiex_pcie_reg_dump,
Amitkumar Karwarfc697152015-05-26 06:34:31 -07003135 .device_dump = mwifiex_pcie_device_dump,
Amitkumar Karwar4c5dae52016-07-26 19:31:44 +05303136 .down_dev = mwifiex_pcie_down_dev,
3137 .up_dev = mwifiex_pcie_up_dev,
Amitkumar Karward930fae2011-10-11 17:41:21 -07003138};
3139
3140/*
3141 * This function initializes the PCIE driver module.
3142 *
3143 * This initiates the semaphore and registers the device with
3144 * PCIE bus.
3145 */
3146static int mwifiex_pcie_init_module(void)
3147{
3148 int ret;
3149
Avinash Patilca8f2112013-02-08 18:18:09 -08003150 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07003151
3152 sema_init(&add_remove_card_sem, 1);
3153
3154 /* Clear the flag in case user removes the card. */
3155 user_rmmod = 0;
3156
3157 ret = pci_register_driver(&mwifiex_pcie);
3158 if (ret)
3159 pr_err("Driver register failed!\n");
3160 else
3161 pr_debug("info: Driver registered successfully!\n");
3162
3163 return ret;
3164}
3165
3166/*
3167 * This function cleans up the PCIE driver.
3168 *
3169 * The following major steps are followed for cleanup -
3170 * - Resume the device if its suspended
3171 * - Disconnect the device if connected
3172 * - Shutdown the firmware
3173 * - Unregister the device from PCIE bus.
3174 */
3175static void mwifiex_pcie_cleanup_module(void)
3176{
3177 if (!down_interruptible(&add_remove_card_sem))
3178 up(&add_remove_card_sem);
3179
3180 /* Set the flag as user is removing this module. */
3181 user_rmmod = 1;
3182
Maithili Hinge2f5872b2015-03-22 23:01:25 -07003183 cancel_work_sync(&pcie_work);
Amitkumar Karward930fae2011-10-11 17:41:21 -07003184 pci_unregister_driver(&mwifiex_pcie);
3185}
3186
3187module_init(mwifiex_pcie_init_module);
3188module_exit(mwifiex_pcie_cleanup_module);
3189
3190MODULE_AUTHOR("Marvell International Ltd.");
3191MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
3192MODULE_VERSION(PCIE_VERSION);
3193MODULE_LICENSE("GPL v2");