blob: b31c9a70ffaaa4de5f0a426966d39eb888b2959a [file] [log] [blame]
Amitkumar Karward930fae2011-10-11 17:41:21 -07001/*
2 * Marvell Wireless LAN device driver: PCIE specific handling
3 *
Xinming Hu65da33f2014-06-19 21:38:57 -07004 * Copyright (C) 2011-2014, Marvell International Ltd.
Amitkumar Karward930fae2011-10-11 17:41:21 -07005 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/firmware.h>
21
22#include "decl.h"
23#include "ioctl.h"
24#include "util.h"
25#include "fw.h"
26#include "main.h"
27#include "wmm.h"
28#include "11n.h"
29#include "pcie.h"
30
31#define PCIE_VERSION "1.0"
32#define DRV_NAME "Marvell mwifiex PCIe"
33
34static u8 user_rmmod;
35
36static struct mwifiex_if_ops pcie_ops;
37
38static struct semaphore add_remove_card_sem;
Amitkumar Karward930fae2011-10-11 17:41:21 -070039
Amitkumar Karwar92c25382014-06-19 21:38:52 -070040static struct memory_type_mapping mem_type_mapping_tbl[] = {
41 {"ITCM", NULL, 0, 0xF0},
42 {"DTCM", NULL, 0, 0xF1},
43 {"SQRAM", NULL, 0, 0xF2},
44 {"IRAM", NULL, 0, 0xF3},
Amitkumar Karwar7e174832014-09-18 07:18:50 -040045 {"APU", NULL, 0, 0xF4},
46 {"CIU", NULL, 0, 0xF5},
47 {"ICU", NULL, 0, 0xF6},
48 {"MAC", NULL, 0, 0xF7},
Amitkumar Karwar92c25382014-06-19 21:38:52 -070049};
50
Avinash Patilfc331462013-01-03 21:21:30 -080051static int
52mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
Aaron Durbindbccc922014-02-07 16:25:50 -080053 size_t size, int flags)
Amitkumar Karward930fae2011-10-11 17:41:21 -070054{
Avinash Patilfc331462013-01-03 21:21:30 -080055 struct pcie_service_card *card = adapter->card;
Aaron Durbindbccc922014-02-07 16:25:50 -080056 struct mwifiex_dma_mapping mapping;
Amitkumar Karward930fae2011-10-11 17:41:21 -070057
Aaron Durbindbccc922014-02-07 16:25:50 -080058 mapping.addr = pci_map_single(card->dev, skb->data, size, flags);
59 if (pci_dma_mapping_error(card->dev, mapping.addr)) {
Avinash Patilfc331462013-01-03 21:21:30 -080060 dev_err(adapter->dev, "failed to map pci memory!\n");
61 return -1;
62 }
Aaron Durbindbccc922014-02-07 16:25:50 -080063 mapping.len = size;
Chin-Ran Lobca463e2014-06-06 19:37:10 -070064 mwifiex_store_mapping(skb, &mapping);
Avinash Patilfc331462013-01-03 21:21:30 -080065 return 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -070066}
67
Aaron Durbindbccc922014-02-07 16:25:50 -080068static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
69 struct sk_buff *skb, int flags)
70{
71 struct pcie_service_card *card = adapter->card;
72 struct mwifiex_dma_mapping mapping;
73
Chin-Ran Lobca463e2014-06-06 19:37:10 -070074 mwifiex_get_mapping(skb, &mapping);
Aaron Durbindbccc922014-02-07 16:25:50 -080075 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
76}
77
Amitkumar Karward930fae2011-10-11 17:41:21 -070078/*
79 * This function reads sleep cookie and checks if FW is ready
80 */
81static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
82{
83 u32 *cookie_addr;
84 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -080085 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
86
87 if (!reg->sleep_cookie)
88 return true;
Amitkumar Karward930fae2011-10-11 17:41:21 -070089
Avinash Patilfc331462013-01-03 21:21:30 -080090 if (card->sleep_cookie_vbase) {
91 cookie_addr = (u32 *)card->sleep_cookie_vbase;
Amitkumar Karward930fae2011-10-11 17:41:21 -070092 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
93 *cookie_addr);
94 if (*cookie_addr == FW_AWAKE_COOKIE)
95 return true;
96 }
97
98 return false;
99}
100
Shuah Khan3266d732013-07-03 10:47:10 -0600101#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700102/*
Bing Zhaofcca8d52013-03-04 16:27:53 -0800103 * Kernel needs to suspend all functions separately. Therefore all
104 * registered functions must have drivers with suspend and resume
105 * methods. Failing that the kernel simply removes the whole card.
106 *
107 * If already not suspended, this function allocates and sends a host
108 * sleep activate request to the firmware and turns off the traffic.
109 */
Shuah Khan3266d732013-07-03 10:47:10 -0600110static int mwifiex_pcie_suspend(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800111{
112 struct mwifiex_adapter *adapter;
113 struct pcie_service_card *card;
114 int hs_actived;
Shuah Khan3266d732013-07-03 10:47:10 -0600115 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800116
117 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900118 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800119 if (!card || !card->adapter) {
120 pr_err("Card or adapter structure is not valid\n");
121 return 0;
122 }
123 } else {
124 pr_err("PCIE device is not specified\n");
125 return 0;
126 }
127
128 adapter = card->adapter;
129
130 hs_actived = mwifiex_enable_hs(adapter);
131
132 /* Indicate device suspended */
133 adapter->is_suspended = true;
Amitkumar Karwarc0dbba62014-03-25 19:01:20 -0700134 adapter->hs_enabling = false;
Bing Zhaofcca8d52013-03-04 16:27:53 -0800135
136 return 0;
137}
138
139/*
140 * Kernel needs to suspend all functions separately. Therefore all
141 * registered functions must have drivers with suspend and resume
142 * methods. Failing that the kernel simply removes the whole card.
143 *
144 * If already not resumed, this function turns on the traffic and
145 * sends a host sleep cancel request to the firmware.
146 */
Shuah Khan3266d732013-07-03 10:47:10 -0600147static int mwifiex_pcie_resume(struct device *dev)
Bing Zhaofcca8d52013-03-04 16:27:53 -0800148{
149 struct mwifiex_adapter *adapter;
150 struct pcie_service_card *card;
Shuah Khan3266d732013-07-03 10:47:10 -0600151 struct pci_dev *pdev = to_pci_dev(dev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800152
153 if (pdev) {
Jingoo Hanb2a31202013-09-09 14:26:51 +0900154 card = pci_get_drvdata(pdev);
Bing Zhaofcca8d52013-03-04 16:27:53 -0800155 if (!card || !card->adapter) {
156 pr_err("Card or adapter structure is not valid\n");
157 return 0;
158 }
159 } else {
160 pr_err("PCIE device is not specified\n");
161 return 0;
162 }
163
164 adapter = card->adapter;
165
166 if (!adapter->is_suspended) {
167 dev_warn(adapter->dev, "Device already resumed\n");
168 return 0;
169 }
170
171 adapter->is_suspended = false;
172
173 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
174 MWIFIEX_ASYNC_CMD);
175
176 return 0;
177}
Bing Zhao8509e822013-03-04 16:27:54 -0800178#endif
Bing Zhaofcca8d52013-03-04 16:27:53 -0800179
180/*
Amitkumar Karward930fae2011-10-11 17:41:21 -0700181 * This function probes an mwifiex device and registers it. It allocates
182 * the card structure, enables PCIE function number and initiates the
183 * device registration and initialization procedure by adding a logical
184 * interface.
185 */
186static int mwifiex_pcie_probe(struct pci_dev *pdev,
187 const struct pci_device_id *ent)
188{
189 struct pcie_service_card *card;
190
191 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700192 pdev->vendor, pdev->device, pdev->revision);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700193
194 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
Joe Perchese404dec2012-01-29 12:56:23 +0000195 if (!card)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700196 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700197
198 card->dev = pdev;
199
Avinash Patildd04e6a2013-02-08 18:18:06 -0800200 if (ent->driver_data) {
201 struct mwifiex_pcie_device *data = (void *)ent->driver_data;
202 card->pcie.firmware = data->firmware;
203 card->pcie.reg = data->reg;
204 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
Amitkumar Karwar828cf222014-02-27 19:35:13 -0800205 card->pcie.tx_buf_size = data->tx_buf_size;
Avinash Patilb4e8aeb2015-02-11 23:12:26 +0530206 card->pcie.can_dump_fw = data->can_dump_fw;
Avinash Patil1fe192d2015-01-23 17:09:19 +0530207 card->pcie.can_ext_scan = data->can_ext_scan;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800208 }
209
Amitkumar Karward930fae2011-10-11 17:41:21 -0700210 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
211 MWIFIEX_PCIE)) {
212 pr_err("%s failed\n", __func__);
213 kfree(card);
214 return -1;
215 }
216
217 return 0;
218}
219
220/*
221 * This function removes the interface and frees up the card structure.
222 */
223static void mwifiex_pcie_remove(struct pci_dev *pdev)
224{
225 struct pcie_service_card *card;
226 struct mwifiex_adapter *adapter;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700227 struct mwifiex_private *priv;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700228
229 card = pci_get_drvdata(pdev);
230 if (!card)
231 return;
232
233 adapter = card->adapter;
234 if (!adapter || !adapter->priv_num)
235 return;
236
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700237 cancel_work_sync(&adapter->iface_work);
238
Amitkumar Karward930fae2011-10-11 17:41:21 -0700239 if (user_rmmod) {
Shuah Khan3266d732013-07-03 10:47:10 -0600240#ifdef CONFIG_PM_SLEEP
Amitkumar Karward930fae2011-10-11 17:41:21 -0700241 if (adapter->is_suspended)
Shuah Khan3266d732013-07-03 10:47:10 -0600242 mwifiex_pcie_resume(&pdev->dev);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700243#endif
244
Amitkumar Karwar848819f2014-02-27 19:35:17 -0800245 mwifiex_deauthenticate_all(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700246
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700247 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700248
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700249 mwifiex_disable_auto_ds(priv);
250
251 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700252 }
253
254 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700255}
256
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700257static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
258{
259 user_rmmod = 1;
260 mwifiex_pcie_remove(pdev);
261
262 return;
263}
264
Benoit Taine9baa3c32014-08-08 15:56:03 +0200265static const struct pci_device_id mwifiex_ids[] = {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700266 {
267 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
268 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
Avinash Patildd04e6a2013-02-08 18:18:06 -0800269 .driver_data = (unsigned long) &mwifiex_pcie8766,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700270 },
Avinash Patilca8f2112013-02-08 18:18:09 -0800271 {
272 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897,
273 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
274 .driver_data = (unsigned long) &mwifiex_pcie8897,
275 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700276 {},
277};
278
279MODULE_DEVICE_TABLE(pci, mwifiex_ids);
280
Shuah Khan3266d732013-07-03 10:47:10 -0600281#ifdef CONFIG_PM_SLEEP
282/* Power Management Hooks */
283static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend,
284 mwifiex_pcie_resume);
285#endif
286
Amitkumar Karward930fae2011-10-11 17:41:21 -0700287/* PCI Device Driver */
288static struct pci_driver __refdata mwifiex_pcie = {
289 .name = "mwifiex_pcie",
290 .id_table = mwifiex_ids,
291 .probe = mwifiex_pcie_probe,
292 .remove = mwifiex_pcie_remove,
Shuah Khan3266d732013-07-03 10:47:10 -0600293#ifdef CONFIG_PM_SLEEP
294 .driver = {
295 .pm = &mwifiex_pcie_pm_ops,
296 },
Amitkumar Karward930fae2011-10-11 17:41:21 -0700297#endif
Amitkumar Karwar43ba6b92013-07-22 19:17:47 -0700298 .shutdown = mwifiex_pcie_shutdown,
Amitkumar Karward930fae2011-10-11 17:41:21 -0700299};
300
301/*
302 * This function writes data into PCIE card register.
303 */
304static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
305{
306 struct pcie_service_card *card = adapter->card;
307
308 iowrite32(data, card->pci_mmap1 + reg);
309
310 return 0;
311}
312
313/*
314 * This function reads data from PCIE card register.
315 */
316static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
317{
318 struct pcie_service_card *card = adapter->card;
319
320 *data = ioread32(card->pci_mmap1 + reg);
321
322 return 0;
323}
324
Amitkumar Karwar92c25382014-06-19 21:38:52 -0700325/* This function reads u8 data from PCIE card register. */
326static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
327 int reg, u8 *data)
328{
329 struct pcie_service_card *card = adapter->card;
330
331 *data = ioread8(card->pci_mmap1 + reg);
332
333 return 0;
334}
335
Amitkumar Karward930fae2011-10-11 17:41:21 -0700336/*
Avinash Patilc0880a22013-03-22 21:49:07 -0700337 * This function adds delay loop to ensure FW is awake before proceeding.
Amitkumar Karward930fae2011-10-11 17:41:21 -0700338 */
Avinash Patilc0880a22013-03-22 21:49:07 -0700339static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700340{
341 int i = 0;
342
Avinash Patilc0880a22013-03-22 21:49:07 -0700343 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -0700344 i++;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -0700345 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700346 /* 50ms max wait */
Avinash Patil3e7a4ff2013-02-25 16:01:34 -0800347 if (i == 5000)
Amitkumar Karward930fae2011-10-11 17:41:21 -0700348 break;
349 }
350
Avinash Patilc0880a22013-03-22 21:49:07 -0700351 return;
352}
353
Avinash Patilc4bc9802014-03-18 22:19:17 -0700354static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
355 u32 max_delay_loop_cnt)
356{
357 struct pcie_service_card *card = adapter->card;
358 u8 *buffer;
359 u32 sleep_cookie, count;
360
361 for (count = 0; count < max_delay_loop_cnt; count++) {
362 buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
363 sleep_cookie = *(u32 *)buffer;
364
365 if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
366 dev_dbg(adapter->dev,
367 "sleep cookie found at count %d\n", count);
368 break;
369 }
370 usleep_range(20, 30);
371 }
372
373 if (count >= max_delay_loop_cnt)
374 dev_dbg(adapter->dev,
375 "max count reached while accessing sleep cookie\n");
376}
377
Avinash Patilc0880a22013-03-22 21:49:07 -0700378/* This function wakes up the card by reading fw_status register. */
379static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
380{
381 u32 fw_status;
382 struct pcie_service_card *card = adapter->card;
383 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
384
Amitkumar Karward930fae2011-10-11 17:41:21 -0700385 dev_dbg(adapter->dev, "event: Wakeup device...\n");
386
Avinash Patilc0880a22013-03-22 21:49:07 -0700387 if (reg->sleep_cookie)
388 mwifiex_pcie_dev_wakeup_delay(adapter);
389
390 /* Reading fw_status register will wakeup device */
391 if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
392 dev_warn(adapter->dev, "Reading fw_status register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700393 return -1;
394 }
395
Avinash Patilc0880a22013-03-22 21:49:07 -0700396 if (reg->sleep_cookie) {
397 mwifiex_pcie_dev_wakeup_delay(adapter);
398 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
399 adapter->ps_state = PS_STATE_AWAKE;
400 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700401
402 return 0;
403}
404
405/*
406 * This function is called after the card has woken up.
407 *
408 * The card configuration register is reset.
409 */
410static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
411{
412 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
413
414 return 0;
415}
416
417/*
418 * This function disables the host interrupt.
419 *
420 * The host interrupt mask is read, the disable bit is reset and
421 * written back to the card host interrupt mask register.
422 */
423static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
424{
425 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
426 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
427 0x00000000)) {
428 dev_warn(adapter->dev, "Disable host interrupt failed\n");
429 return -1;
430 }
431 }
432
433 return 0;
434}
435
436/*
437 * This function enables the host interrupt.
438 *
439 * The host interrupt enable mask is written to the card
440 * host interrupt mask register.
441 */
442static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
443{
444 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
445 /* Simply write the mask to the register */
446 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
447 HOST_INTR_MASK)) {
448 dev_warn(adapter->dev, "Enable host interrupt failed\n");
449 return -1;
450 }
451 }
452
453 return 0;
454}
455
456/*
Avinash Patil07324842013-02-08 18:18:07 -0800457 * This function initializes TX buffer ring descriptors
458 */
459static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter)
460{
461 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800462 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800463 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800464 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800465 int i;
466
467 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
468 card->tx_buf_list[i] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -0800469 if (reg->pfu_enabled) {
470 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
471 (sizeof(*desc2) * i);
472 desc2 = card->txbd_ring[i];
473 memset(desc2, 0, sizeof(*desc2));
474 } else {
475 card->txbd_ring[i] = (void *)card->txbd_ring_vbase +
476 (sizeof(*desc) * i);
477 desc = card->txbd_ring[i];
478 memset(desc, 0, sizeof(*desc));
479 }
Avinash Patil07324842013-02-08 18:18:07 -0800480 }
481
482 return 0;
483}
484
485/* This function initializes RX buffer ring descriptors. Each SKB is allocated
486 * here and after mapping PCI memory, its physical address is assigned to
487 * PCIE Rx buffer descriptor's physical address.
488 */
489static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
490{
491 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800492 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800493 struct sk_buff *skb;
494 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800495 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800496 dma_addr_t buf_pa;
497 int i;
498
499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
500 /* Allocate skb here so that firmware can DMA data from it */
Avinash Patil62159942015-03-13 17:37:52 +0530501 skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
502 GFP_KERNEL | GFP_DMA);
Avinash Patil07324842013-02-08 18:18:07 -0800503 if (!skb) {
504 dev_err(adapter->dev,
505 "Unable to allocate skb for RX ring.\n");
506 kfree(card->rxbd_ring_vbase);
507 return -ENOMEM;
508 }
509
510 if (mwifiex_map_pci_memory(adapter, skb,
511 MWIFIEX_RX_DATA_BUF_SIZE,
512 PCI_DMA_FROMDEVICE))
513 return -1;
514
Aaron Durbindbccc922014-02-07 16:25:50 -0800515 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800516
517 dev_dbg(adapter->dev,
518 "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
519 skb, skb->len, skb->data, (u32)buf_pa,
520 (u32)((u64)buf_pa >> 32));
521
522 card->rx_buf_list[i] = skb;
Avinash Patilca8f2112013-02-08 18:18:09 -0800523 if (reg->pfu_enabled) {
524 card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase +
525 (sizeof(*desc2) * i);
526 desc2 = card->rxbd_ring[i];
527 desc2->paddr = buf_pa;
528 desc2->len = (u16)skb->len;
529 desc2->frag_len = (u16)skb->len;
530 desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop;
531 desc2->offset = 0;
532 } else {
533 card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase +
534 (sizeof(*desc) * i));
535 desc = card->rxbd_ring[i];
536 desc->paddr = buf_pa;
537 desc->len = (u16)skb->len;
538 desc->flags = 0;
539 }
Avinash Patil07324842013-02-08 18:18:07 -0800540 }
541
542 return 0;
543}
544
545/* This function initializes event buffer ring descriptors. Each SKB is
546 * allocated here and after mapping PCI memory, its physical address is assigned
547 * to PCIE Rx buffer descriptor's physical address
548 */
549static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
550{
551 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800552 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800553 struct sk_buff *skb;
554 dma_addr_t buf_pa;
555 int i;
556
557 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
558 /* Allocate skb here so that firmware can DMA data from it */
559 skb = dev_alloc_skb(MAX_EVENT_SIZE);
560 if (!skb) {
561 dev_err(adapter->dev,
562 "Unable to allocate skb for EVENT buf.\n");
563 kfree(card->evtbd_ring_vbase);
564 return -ENOMEM;
565 }
566 skb_put(skb, MAX_EVENT_SIZE);
567
568 if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
569 PCI_DMA_FROMDEVICE))
570 return -1;
571
Aaron Durbindbccc922014-02-07 16:25:50 -0800572 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patil07324842013-02-08 18:18:07 -0800573
574 dev_dbg(adapter->dev,
575 "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n",
576 skb, skb->len, skb->data, (u32)buf_pa,
577 (u32)((u64)buf_pa >> 32));
578
579 card->evt_buf_list[i] = skb;
580 card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase +
581 (sizeof(*desc) * i));
Avinash Patil07324842013-02-08 18:18:07 -0800582 desc = card->evtbd_ring[i];
583 desc->paddr = buf_pa;
584 desc->len = (u16)skb->len;
585 desc->flags = 0;
586 }
587
588 return 0;
589}
590
591/* This function cleans up TX buffer rings. If any of the buffer list has valid
592 * SKB address, associated SKB is freed.
593 */
594static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter)
595{
596 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800597 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800598 struct sk_buff *skb;
599 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800600 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800601 int i;
602
603 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800604 if (reg->pfu_enabled) {
605 desc2 = card->txbd_ring[i];
606 if (card->tx_buf_list[i]) {
607 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800608 mwifiex_unmap_pci_memory(adapter, skb,
609 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800610 dev_kfree_skb_any(skb);
611 }
612 memset(desc2, 0, sizeof(*desc2));
613 } else {
614 desc = card->txbd_ring[i];
615 if (card->tx_buf_list[i]) {
616 skb = card->tx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800617 mwifiex_unmap_pci_memory(adapter, skb,
618 PCI_DMA_TODEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800619 dev_kfree_skb_any(skb);
620 }
621 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800622 }
623 card->tx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800624 }
625
626 return;
627}
628
629/* This function cleans up RX buffer rings. If any of the buffer list has valid
630 * SKB address, associated SKB is freed.
631 */
632static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter)
633{
634 struct pcie_service_card *card = adapter->card;
Avinash Patilca8f2112013-02-08 18:18:09 -0800635 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patil07324842013-02-08 18:18:07 -0800636 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -0800637 struct mwifiex_pfu_buf_desc *desc2;
Avinash Patil07324842013-02-08 18:18:07 -0800638 struct sk_buff *skb;
639 int i;
640
641 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
Avinash Patilca8f2112013-02-08 18:18:09 -0800642 if (reg->pfu_enabled) {
643 desc2 = card->rxbd_ring[i];
644 if (card->rx_buf_list[i]) {
645 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800646 mwifiex_unmap_pci_memory(adapter, skb,
647 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800648 dev_kfree_skb_any(skb);
649 }
650 memset(desc2, 0, sizeof(*desc2));
651 } else {
652 desc = card->rxbd_ring[i];
653 if (card->rx_buf_list[i]) {
654 skb = card->rx_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800655 mwifiex_unmap_pci_memory(adapter, skb,
656 PCI_DMA_FROMDEVICE);
Avinash Patilca8f2112013-02-08 18:18:09 -0800657 dev_kfree_skb_any(skb);
658 }
659 memset(desc, 0, sizeof(*desc));
Avinash Patil07324842013-02-08 18:18:07 -0800660 }
Avinash Patilca8f2112013-02-08 18:18:09 -0800661 card->rx_buf_list[i] = NULL;
Avinash Patil07324842013-02-08 18:18:07 -0800662 }
663
664 return;
665}
666
667/* This function cleans up event buffer rings. If any of the buffer list has
668 * valid SKB address, associated SKB is freed.
669 */
670static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter)
671{
672 struct pcie_service_card *card = adapter->card;
Avinash Patile05dc3e2013-02-08 18:18:08 -0800673 struct mwifiex_evt_buf_desc *desc;
Avinash Patil07324842013-02-08 18:18:07 -0800674 struct sk_buff *skb;
675 int i;
676
677 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
678 desc = card->evtbd_ring[i];
679 if (card->evt_buf_list[i]) {
680 skb = card->evt_buf_list[i];
Aaron Durbindbccc922014-02-07 16:25:50 -0800681 mwifiex_unmap_pci_memory(adapter, skb,
682 PCI_DMA_FROMDEVICE);
Avinash Patil07324842013-02-08 18:18:07 -0800683 dev_kfree_skb_any(skb);
684 }
685 card->evt_buf_list[i] = NULL;
686 memset(desc, 0, sizeof(*desc));
687 }
688
689 return;
690}
691
692/* This function creates buffer descriptor ring for TX
Amitkumar Karward930fae2011-10-11 17:41:21 -0700693 */
694static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
695{
696 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800697 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700698
699 /*
700 * driver maintaines the write pointer and firmware maintaines the read
701 * pointer. The write pointer starts at 0 (zero) while the read pointer
702 * starts at zero with rollover bit set
703 */
704 card->txbd_wrptr = 0;
Avinash Patilca8f2112013-02-08 18:18:09 -0800705
706 if (reg->pfu_enabled)
707 card->txbd_rdptr = 0;
708 else
709 card->txbd_rdptr |= reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700710
711 /* allocate shared memory for the BD ring and divide the same in to
712 several descriptors */
Avinash Patilca8f2112013-02-08 18:18:09 -0800713 if (reg->pfu_enabled)
714 card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
715 MWIFIEX_MAX_TXRX_BD;
716 else
717 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
718 MWIFIEX_MAX_TXRX_BD;
719
Amitkumar Karward930fae2011-10-11 17:41:21 -0700720 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700721 card->txbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800722 card->txbd_ring_vbase = pci_alloc_consistent(card->dev,
723 card->txbd_ring_size,
724 &card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700725 if (!card->txbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800726 dev_err(adapter->dev,
727 "allocate consistent memory (%d bytes) failed!\n",
728 card->txbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800729 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700730 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700731 dev_dbg(adapter->dev,
732 "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800733 card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700734 (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700735
Avinash Patil07324842013-02-08 18:18:07 -0800736 return mwifiex_init_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700737}
738
739static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
740{
741 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800742 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700743
Avinash Patil07324842013-02-08 18:18:07 -0800744 mwifiex_cleanup_txq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700745
Avinash Patilfc331462013-01-03 21:21:30 -0800746 if (card->txbd_ring_vbase)
747 pci_free_consistent(card->dev, card->txbd_ring_size,
748 card->txbd_ring_vbase,
749 card->txbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700750 card->txbd_ring_size = 0;
751 card->txbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800752 card->txbd_rdptr = 0 | reg->tx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700753 card->txbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800754 card->txbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700755
756 return 0;
757}
758
759/*
760 * This function creates buffer descriptor ring for RX
761 */
762static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
763{
764 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800765 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700766
767 /*
768 * driver maintaines the read pointer and firmware maintaines the write
769 * pointer. The write pointer starts at 0 (zero) while the read pointer
770 * starts at zero with rollover bit set
771 */
772 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800773 card->rxbd_rdptr = reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700774
Avinash Patilca8f2112013-02-08 18:18:09 -0800775 if (reg->pfu_enabled)
776 card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) *
777 MWIFIEX_MAX_TXRX_BD;
778 else
779 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
780 MWIFIEX_MAX_TXRX_BD;
781
Amitkumar Karward930fae2011-10-11 17:41:21 -0700782 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700783 card->rxbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800784 card->rxbd_ring_vbase = pci_alloc_consistent(card->dev,
785 card->rxbd_ring_size,
786 &card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700787 if (!card->rxbd_ring_vbase) {
Avinash Patilfc331462013-01-03 21:21:30 -0800788 dev_err(adapter->dev,
789 "allocate consistent memory (%d bytes) failed!\n",
790 card->rxbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800791 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700792 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700793
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700794 dev_dbg(adapter->dev,
795 "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
796 card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
797 (u32)((u64)card->rxbd_ring_pbase >> 32),
798 card->rxbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700799
Avinash Patil07324842013-02-08 18:18:07 -0800800 return mwifiex_init_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700801}
802
803/*
804 * This function deletes Buffer descriptor ring for RX
805 */
806static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
807{
808 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800809 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700810
Avinash Patil07324842013-02-08 18:18:07 -0800811 mwifiex_cleanup_rxq_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700812
Avinash Patilfc331462013-01-03 21:21:30 -0800813 if (card->rxbd_ring_vbase)
814 pci_free_consistent(card->dev, card->rxbd_ring_size,
815 card->rxbd_ring_vbase,
816 card->rxbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700817 card->rxbd_ring_size = 0;
818 card->rxbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800819 card->rxbd_rdptr = 0 | reg->rx_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700820 card->rxbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800821 card->rxbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700822
823 return 0;
824}
825
826/*
827 * This function creates buffer descriptor ring for Events
828 */
829static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
830{
831 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800832 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700833
834 /*
835 * driver maintaines the read pointer and firmware maintaines the write
836 * pointer. The write pointer starts at 0 (zero) while the read pointer
837 * starts at zero with rollover bit set
838 */
839 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800840 card->evtbd_rdptr = reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700841
Avinash Patile05dc3e2013-02-08 18:18:08 -0800842 card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) *
Avinash Patilca8f2112013-02-08 18:18:09 -0800843 MWIFIEX_MAX_EVT_BD;
844
Amitkumar Karward930fae2011-10-11 17:41:21 -0700845 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700846 card->evtbd_ring_size);
Avinash Patilfc331462013-01-03 21:21:30 -0800847 card->evtbd_ring_vbase = pci_alloc_consistent(card->dev,
848 card->evtbd_ring_size,
849 &card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700850 if (!card->evtbd_ring_vbase) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700851 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -0800852 "allocate consistent memory (%d bytes) failed!\n",
853 card->evtbd_ring_size);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -0800854 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700855 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700856
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700857 dev_dbg(adapter->dev,
858 "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
859 card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
860 (u32)((u64)card->evtbd_ring_pbase >> 32),
861 card->evtbd_ring_size);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700862
Avinash Patil07324842013-02-08 18:18:07 -0800863 return mwifiex_pcie_init_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700864}
865
866/*
867 * This function deletes Buffer descriptor ring for Events
868 */
869static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
870{
871 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800872 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700873
Avinash Patil07324842013-02-08 18:18:07 -0800874 mwifiex_cleanup_evt_ring(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700875
Avinash Patilfc331462013-01-03 21:21:30 -0800876 if (card->evtbd_ring_vbase)
877 pci_free_consistent(card->dev, card->evtbd_ring_size,
878 card->evtbd_ring_vbase,
879 card->evtbd_ring_pbase);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700880 card->evtbd_wrptr = 0;
Avinash Patildd04e6a2013-02-08 18:18:06 -0800881 card->evtbd_rdptr = 0 | reg->evt_rollover_ind;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700882 card->evtbd_ring_size = 0;
883 card->evtbd_ring_vbase = NULL;
Avinash Patilfc331462013-01-03 21:21:30 -0800884 card->evtbd_ring_pbase = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700885
886 return 0;
887}
888
889/*
890 * This function allocates a buffer for CMDRSP
891 */
892static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
893{
894 struct pcie_service_card *card = adapter->card;
895 struct sk_buff *skb;
896
897 /* Allocate memory for receiving command response data */
898 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
899 if (!skb) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -0700900 dev_err(adapter->dev,
901 "Unable to allocate skb for command response data.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700902 return -ENOMEM;
903 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700904 skb_put(skb, MWIFIEX_UPLD_SIZE);
Avinash Patilfc331462013-01-03 21:21:30 -0800905 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
906 PCI_DMA_FROMDEVICE))
907 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700908
Avinash Patilfc331462013-01-03 21:21:30 -0800909 card->cmdrsp_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700910
911 return 0;
912}
913
914/*
915 * This function deletes a buffer for CMDRSP
916 */
917static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
918{
919 struct pcie_service_card *card;
920
921 if (!adapter)
922 return 0;
923
924 card = adapter->card;
925
Avinash Patilfc331462013-01-03 21:21:30 -0800926 if (card && card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800927 mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf,
928 PCI_DMA_FROMDEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -0700929 dev_kfree_skb_any(card->cmdrsp_buf);
Avinash Patilfc331462013-01-03 21:21:30 -0800930 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700931
Avinash Patilfc331462013-01-03 21:21:30 -0800932 if (card && card->cmd_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -0800933 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
934 PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -0800935 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700936 return 0;
937}
938
939/*
940 * This function allocates a buffer for sleep cookie
941 */
942static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
943{
Amitkumar Karward930fae2011-10-11 17:41:21 -0700944 struct pcie_service_card *card = adapter->card;
945
Avinash Patilfc331462013-01-03 21:21:30 -0800946 card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32),
947 &card->sleep_cookie_pbase);
948 if (!card->sleep_cookie_vbase) {
949 dev_err(adapter->dev, "pci_alloc_consistent failed!\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -0700950 return -ENOMEM;
951 }
Amitkumar Karward930fae2011-10-11 17:41:21 -0700952 /* Init val of Sleep Cookie */
Avinash Patilfc331462013-01-03 21:21:30 -0800953 *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700954
955 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
Avinash Patilfc331462013-01-03 21:21:30 -0800956 *((u32 *)card->sleep_cookie_vbase));
Amitkumar Karward930fae2011-10-11 17:41:21 -0700957
958 return 0;
959}
960
961/*
962 * This function deletes buffer for sleep cookie
963 */
964static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
965{
966 struct pcie_service_card *card;
967
968 if (!adapter)
969 return 0;
970
971 card = adapter->card;
972
Avinash Patilfc331462013-01-03 21:21:30 -0800973 if (card && card->sleep_cookie_vbase) {
974 pci_free_consistent(card->dev, sizeof(u32),
975 card->sleep_cookie_vbase,
976 card->sleep_cookie_pbase);
977 card->sleep_cookie_vbase = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -0700978 }
979
980 return 0;
981}
982
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800983/* This function flushes the TX buffer descriptor ring
984 * This function defined as handler is also called while cleaning TXRX
985 * during disconnect/ bss stop.
986 */
987static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter)
988{
989 struct pcie_service_card *card = adapter->card;
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800990
Avinash Patil48f4d912013-02-20 21:12:58 -0800991 if (!mwifiex_pcie_txbd_empty(card, card->txbd_rdptr)) {
Avinash Patilfbd7e7a2013-01-03 21:21:31 -0800992 card->txbd_flush = 1;
993 /* write pointer already set at last send
994 * send dnld-rdy intr again, wait for completion.
995 */
996 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
997 CPU_INTR_DNLD_RDY)) {
998 dev_err(adapter->dev,
999 "failed to assert dnld-rdy interrupt.\n");
1000 return -1;
1001 }
1002 }
1003 return 0;
1004}
1005
Amitkumar Karward930fae2011-10-11 17:41:21 -07001006/*
Avinash Patile7f767a2013-01-03 21:21:32 -08001007 * This function unmaps and frees downloaded data buffer
Amitkumar Karward930fae2011-10-11 17:41:21 -07001008 */
Avinash Patile7f767a2013-01-03 21:21:32 -08001009static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001010{
Avinash Patile7f767a2013-01-03 21:21:32 -08001011 struct sk_buff *skb;
Avinash Patilca8f2112013-02-08 18:18:09 -08001012 u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001013 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001014 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001015 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001016 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001017
1018 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1019 mwifiex_pm_wakeup_card(adapter);
1020
1021 /* Read the TX ring read pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001022 if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001023 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001024 "SEND COMP: failed to read reg->tx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001025 return -1;
1026 }
1027
Avinash Patile7f767a2013-01-03 21:21:32 -08001028 dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n",
1029 card->txbd_rdptr, rdptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001030
Avinash Patilca8f2112013-02-08 18:18:09 -08001031 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001032 /* free from previous txbd_rdptr to current txbd_rdptr */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001033 while (((card->txbd_rdptr & reg->tx_mask) !=
1034 (rdptr & reg->tx_mask)) ||
1035 ((card->txbd_rdptr & reg->tx_rollover_ind) !=
1036 (rdptr & reg->tx_rollover_ind))) {
Avinash Patilca8f2112013-02-08 18:18:09 -08001037 wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >>
1038 reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001039
1040 skb = card->tx_buf_list[wrdoneidx];
Aaron Durbindbccc922014-02-07 16:25:50 -08001041
Avinash Patile7f767a2013-01-03 21:21:32 -08001042 if (skb) {
1043 dev_dbg(adapter->dev,
1044 "SEND COMP: Detach skb %p at txbd_rdidx=%d\n",
1045 skb, wrdoneidx);
Aaron Durbindbccc922014-02-07 16:25:50 -08001046 mwifiex_unmap_pci_memory(adapter, skb,
1047 PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001048
1049 unmap_count++;
1050
1051 if (card->txbd_flush)
1052 mwifiex_write_data_complete(adapter, skb, 0,
1053 -1);
1054 else
1055 mwifiex_write_data_complete(adapter, skb, 0, 0);
1056 }
1057
1058 card->tx_buf_list[wrdoneidx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001059
1060 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001061 desc2 = card->txbd_ring[wrdoneidx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001062 memset(desc2, 0, sizeof(*desc2));
1063 } else {
1064 desc = card->txbd_ring[wrdoneidx];
1065 memset(desc, 0, sizeof(*desc));
1066 }
1067 switch (card->dev->device) {
1068 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1069 card->txbd_rdptr++;
1070 break;
1071 case PCIE_DEVICE_ID_MARVELL_88W8897:
1072 card->txbd_rdptr += reg->ring_tx_start_ptr;
1073 break;
1074 }
1075
Avinash Patile7f767a2013-01-03 21:21:32 -08001076
Avinash Patildd04e6a2013-02-08 18:18:06 -08001077 if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs)
Avinash Patile7f767a2013-01-03 21:21:32 -08001078 card->txbd_rdptr = ((card->txbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001079 reg->tx_rollover_ind) ^
1080 reg->tx_rollover_ind);
Avinash Patile7f767a2013-01-03 21:21:32 -08001081 }
1082
1083 if (unmap_count)
1084 adapter->data_sent = false;
1085
1086 if (card->txbd_flush) {
Avinash Patil3d482032013-02-15 21:37:54 -08001087 if (mwifiex_pcie_txbd_empty(card, card->txbd_rdptr))
Avinash Patile7f767a2013-01-03 21:21:32 -08001088 card->txbd_flush = 0;
1089 else
1090 mwifiex_clean_pcie_ring_buf(adapter);
1091 }
1092
1093 return 0;
1094}
1095
1096/* This function sends data buffer to device. First 4 bytes of payload
1097 * are filled with payload length and payload type. Then this payload
1098 * is mapped to PCI device memory. Tx ring pointers are advanced accordingly.
1099 * Download ready interrupt to FW is deffered if Tx ring is not full and
1100 * additional payload can be accomodated.
Avinash Patil8d767dc2014-05-13 19:50:13 -07001101 * Caller must ensure tx_param parameter to this function is not NULL.
Avinash Patile7f767a2013-01-03 21:21:32 -08001102 */
1103static int
1104mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb,
1105 struct mwifiex_tx_param *tx_param)
1106{
1107 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001108 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001109 u32 wrindx, num_tx_buffs, rx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001110 int ret;
1111 dma_addr_t buf_pa;
Bing Zhao99310782013-03-04 16:27:55 -08001112 struct mwifiex_pcie_buf_desc *desc = NULL;
1113 struct mwifiex_pfu_buf_desc *desc2 = NULL;
Avinash Patile7f767a2013-01-03 21:21:32 -08001114 __le16 *tmp;
1115
1116 if (!(skb->data && skb->len)) {
1117 dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n",
1118 __func__, skb->data, skb->len);
1119 return -1;
1120 }
1121
1122 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1123 mwifiex_pm_wakeup_card(adapter);
1124
Avinash Patilca8f2112013-02-08 18:18:09 -08001125 num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr;
Avinash Patile7f767a2013-01-03 21:21:32 -08001126 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n",
1127 card->txbd_rdptr, card->txbd_wrptr);
1128 if (mwifiex_pcie_txbd_not_full(card)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001129 u8 *payload;
1130
1131 adapter->data_sent = true;
Avinash Patile7f767a2013-01-03 21:21:32 -08001132 payload = skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001133 tmp = (__le16 *)&payload[0];
1134 *tmp = cpu_to_le16((u16)skb->len);
1135 tmp = (__le16 *)&payload[2];
1136 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
Avinash Patile7f767a2013-01-03 21:21:32 -08001137
Aaron Durbindbccc922014-02-07 16:25:50 -08001138 if (mwifiex_map_pci_memory(adapter, skb, skb->len,
Avinash Patile7f767a2013-01-03 21:21:32 -08001139 PCI_DMA_TODEVICE))
1140 return -1;
1141
Avinash Patilca8f2112013-02-08 18:18:09 -08001142 wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr;
Aaron Durbindbccc922014-02-07 16:25:50 -08001143 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile7f767a2013-01-03 21:21:32 -08001144 card->tx_buf_list[wrindx] = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001145
Avinash Patilca8f2112013-02-08 18:18:09 -08001146 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001147 desc2 = card->txbd_ring[wrindx];
Avinash Patilca8f2112013-02-08 18:18:09 -08001148 desc2->paddr = buf_pa;
1149 desc2->len = (u16)skb->len;
1150 desc2->frag_len = (u16)skb->len;
1151 desc2->offset = 0;
1152 desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1153 MWIFIEX_BD_FLAG_LAST_DESC;
1154 } else {
1155 desc = card->txbd_ring[wrindx];
1156 desc->paddr = buf_pa;
1157 desc->len = (u16)skb->len;
1158 desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
1159 MWIFIEX_BD_FLAG_LAST_DESC;
1160 }
1161
1162 switch (card->dev->device) {
1163 case PCIE_DEVICE_ID_MARVELL_88W8766P:
1164 card->txbd_wrptr++;
1165 break;
1166 case PCIE_DEVICE_ID_MARVELL_88W8897:
1167 card->txbd_wrptr += reg->ring_tx_start_ptr;
1168 break;
1169 }
1170
1171 if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs)
Amitkumar Karward930fae2011-10-11 17:41:21 -07001172 card->txbd_wrptr = ((card->txbd_wrptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001173 reg->tx_rollover_ind) ^
1174 reg->tx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001175
Avinash Patilca8f2112013-02-08 18:18:09 -08001176 rx_val = card->rxbd_rdptr & reg->rx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001177 /* Write the TX ring write pointer in to reg->tx_wrptr */
1178 if (mwifiex_write_reg(adapter, reg->tx_wrptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001179 card->txbd_wrptr | rx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001180 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001181 "SEND DATA: failed to write reg->tx_wrptr\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001182 ret = -1;
1183 goto done_unmap;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001184 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001185 if ((mwifiex_pcie_txbd_not_full(card)) &&
1186 tx_param->next_pkt_len) {
1187 /* have more packets and TxBD still can hold more */
1188 dev_dbg(adapter->dev,
1189 "SEND DATA: delay dnld-rdy interrupt.\n");
1190 adapter->data_sent = false;
1191 } else {
1192 /* Send the TX ready interrupt */
1193 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1194 CPU_INTR_DNLD_RDY)) {
1195 dev_err(adapter->dev,
1196 "SEND DATA: failed to assert dnld-rdy interrupt.\n");
1197 ret = -1;
1198 goto done_unmap;
1199 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001200 }
1201 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001202 "%#x> and sent packet to firmware successfully\n",
Avinash Patile7f767a2013-01-03 21:21:32 -08001203 card->txbd_rdptr, card->txbd_wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001204 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001205 dev_dbg(adapter->dev,
1206 "info: TX Ring full, can't send packets to fw\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001207 adapter->data_sent = true;
1208 /* Send the TX ready interrupt */
1209 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1210 CPU_INTR_DNLD_RDY))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001211 dev_err(adapter->dev,
1212 "SEND DATA: failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001213 return -EBUSY;
1214 }
1215
Avinash Patile7f767a2013-01-03 21:21:32 -08001216 return -EINPROGRESS;
1217done_unmap:
Aaron Durbindbccc922014-02-07 16:25:50 -08001218 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001219 card->tx_buf_list[wrindx] = NULL;
Avinash Patilca8f2112013-02-08 18:18:09 -08001220 if (reg->pfu_enabled)
1221 memset(desc2, 0, sizeof(*desc2));
1222 else
1223 memset(desc, 0, sizeof(*desc));
1224
Avinash Patile7f767a2013-01-03 21:21:32 -08001225 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001226}
1227
1228/*
1229 * This function handles received buffer ring and
1230 * dispatches packets to upper
1231 */
1232static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1233{
1234 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001235 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001236 u32 wrptr, rd_index, tx_val;
Avinash Patile7f767a2013-01-03 21:21:32 -08001237 dma_addr_t buf_pa;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001238 int ret = 0;
1239 struct sk_buff *skb_tmp = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001240 struct mwifiex_pcie_buf_desc *desc;
Avinash Patilca8f2112013-02-08 18:18:09 -08001241 struct mwifiex_pfu_buf_desc *desc2;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001242
Avinash Patile7f767a2013-01-03 21:21:32 -08001243 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1244 mwifiex_pm_wakeup_card(adapter);
1245
Amitkumar Karward930fae2011-10-11 17:41:21 -07001246 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001247 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001248 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001249 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001250 ret = -1;
1251 goto done;
1252 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001253 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001254
Avinash Patildd04e6a2013-02-08 18:18:06 -08001255 while (((wrptr & reg->rx_mask) !=
1256 (card->rxbd_rdptr & reg->rx_mask)) ||
1257 ((wrptr & reg->rx_rollover_ind) ==
1258 (card->rxbd_rdptr & reg->rx_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001259 struct sk_buff *skb_data;
1260 u16 rx_len;
Avinash Patile7f767a2013-01-03 21:21:32 -08001261 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001262
Avinash Patildd04e6a2013-02-08 18:18:06 -08001263 rd_index = card->rxbd_rdptr & reg->rx_mask;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001264 skb_data = card->rx_buf_list[rd_index];
1265
Amitkumar Karwarbb8e6a12014-02-18 15:41:55 -08001266 /* If skb allocation was failed earlier for Rx packet,
1267 * rx_buf_list[rd_index] would have been left with a NULL.
1268 */
1269 if (!skb_data)
1270 return -ENOMEM;
1271
Aaron Durbindbccc922014-02-07 16:25:50 -08001272 mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE);
Avinash Patile7f767a2013-01-03 21:21:32 -08001273 card->rx_buf_list[rd_index] = NULL;
1274
Amitkumar Karward930fae2011-10-11 17:41:21 -07001275 /* Get data length from interface header -
Avinash Patile7f767a2013-01-03 21:21:32 -08001276 * first 2 bytes for len, next 2 bytes is for type
1277 */
1278 pkt_len = *((__le16 *)skb_data->data);
1279 rx_len = le16_to_cpu(pkt_len);
Avinash Patil42a028a2014-09-12 20:08:47 +05301280 if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
1281 rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
1282 dev_err(adapter->dev,
1283 "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
1284 rx_len, card->rxbd_rdptr, wrptr);
1285 dev_kfree_skb_any(skb_data);
1286 } else {
1287 skb_put(skb_data, rx_len);
1288 dev_dbg(adapter->dev,
1289 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1290 card->rxbd_rdptr, wrptr, rx_len);
1291 skb_pull(skb_data, INTF_HEADER_LEN);
Avinash Patil6e251172014-09-12 20:08:59 +05301292 if (adapter->rx_work_enabled) {
Avinash Patil6e251172014-09-12 20:08:59 +05301293 skb_queue_tail(&adapter->rx_data_q, skb_data);
Avinash Patil6e251172014-09-12 20:08:59 +05301294 adapter->data_received = true;
1295 atomic_inc(&adapter->rx_pending);
1296 } else {
1297 mwifiex_handle_rx_packet(adapter, skb_data);
1298 }
Avinash Patil42a028a2014-09-12 20:08:47 +05301299 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001300
Avinash Patil62159942015-03-13 17:37:52 +05301301 skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1302 GFP_KERNEL | GFP_DMA);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001303 if (!skb_tmp) {
Avinash Patile7f767a2013-01-03 21:21:32 -08001304 dev_err(adapter->dev,
1305 "Unable to allocate skb.\n");
1306 return -ENOMEM;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001307 }
1308
Avinash Patile7f767a2013-01-03 21:21:32 -08001309 if (mwifiex_map_pci_memory(adapter, skb_tmp,
1310 MWIFIEX_RX_DATA_BUF_SIZE,
1311 PCI_DMA_FROMDEVICE))
1312 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001313
Aaron Durbindbccc922014-02-07 16:25:50 -08001314 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp);
Avinash Patile7f767a2013-01-03 21:21:32 -08001315
1316 dev_dbg(adapter->dev,
1317 "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n",
1318 skb_tmp, rd_index);
1319 card->rx_buf_list[rd_index] = skb_tmp;
Avinash Patilca8f2112013-02-08 18:18:09 -08001320
1321 if (reg->pfu_enabled) {
Joe Perches45d18c52014-03-24 13:15:39 -07001322 desc2 = card->rxbd_ring[rd_index];
Avinash Patilca8f2112013-02-08 18:18:09 -08001323 desc2->paddr = buf_pa;
1324 desc2->len = skb_tmp->len;
1325 desc2->frag_len = skb_tmp->len;
1326 desc2->offset = 0;
1327 desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop;
1328 } else {
1329 desc = card->rxbd_ring[rd_index];
1330 desc->paddr = buf_pa;
1331 desc->len = skb_tmp->len;
1332 desc->flags = 0;
1333 }
Avinash Patile7f767a2013-01-03 21:21:32 -08001334
Avinash Patildd04e6a2013-02-08 18:18:06 -08001335 if ((++card->rxbd_rdptr & reg->rx_mask) ==
Amitkumar Karward930fae2011-10-11 17:41:21 -07001336 MWIFIEX_MAX_TXRX_BD) {
1337 card->rxbd_rdptr = ((card->rxbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001338 reg->rx_rollover_ind) ^
1339 reg->rx_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001340 }
1341 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001342 card->rxbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001343
Avinash Patilca8f2112013-02-08 18:18:09 -08001344 tx_val = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001345 /* Write the RX ring read pointer in to reg->rx_rdptr */
1346 if (mwifiex_write_reg(adapter, reg->rx_rdptr,
Avinash Patilca8f2112013-02-08 18:18:09 -08001347 card->rxbd_rdptr | tx_val)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001348 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001349 "RECV DATA: failed to write reg->rx_rdptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001350 ret = -1;
1351 goto done;
1352 }
1353
1354 /* Read the RX ring Write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001355 if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001356 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001357 "RECV DATA: failed to read reg->rx_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001358 ret = -1;
1359 goto done;
1360 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001361 dev_dbg(adapter->dev,
1362 "info: RECV DATA: Rcvd packet from fw successfully\n");
Avinash Patile7f767a2013-01-03 21:21:32 -08001363 card->rxbd_wrptr = wrptr;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001364 }
1365
1366done:
Amitkumar Karward930fae2011-10-11 17:41:21 -07001367 return ret;
1368}
1369
1370/*
1371 * This function downloads the boot command to device
1372 */
1373static int
1374mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1375{
Avinash Patilfc331462013-01-03 21:21:30 -08001376 dma_addr_t buf_pa;
1377 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001378 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001379
Avinash Patilfc331462013-01-03 21:21:30 -08001380 if (!(skb->data && skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001381 dev_err(adapter->dev,
Avinash Patilfc331462013-01-03 21:21:30 -08001382 "Invalid parameter in %s <%p. len %d>\n",
1383 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001384 return -1;
1385 }
1386
Avinash Patilfc331462013-01-03 21:21:30 -08001387 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE))
1388 return -1;
1389
Aaron Durbindbccc922014-02-07 16:25:50 -08001390 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patilfc331462013-01-03 21:21:30 -08001391
Avinash Patildd04e6a2013-02-08 18:18:06 -08001392 /* Write the lower 32bits of the physical address to low command
1393 * address scratch register
1394 */
1395 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001396 dev_err(adapter->dev,
1397 "%s: failed to write download command to boot code.\n",
1398 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001399 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001400 return -1;
1401 }
1402
Avinash Patildd04e6a2013-02-08 18:18:06 -08001403 /* Write the upper 32bits of the physical address to high command
1404 * address scratch register
1405 */
1406 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001407 (u32)((u64)buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001408 dev_err(adapter->dev,
1409 "%s: failed to write download command to boot code.\n",
1410 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001411 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001412 return -1;
1413 }
1414
Avinash Patildd04e6a2013-02-08 18:18:06 -08001415 /* Write the command length to cmd_size scratch register */
1416 if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001417 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001418 "%s: failed to write command len to cmd_size scratch reg\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001419 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001420 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001421 return -1;
1422 }
1423
1424 /* Ring the door bell */
1425 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1426 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001427 dev_err(adapter->dev,
1428 "%s: failed to assert door-bell intr\n", __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001429 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001430 return -1;
1431 }
1432
1433 return 0;
1434}
1435
Avinash Patilc6d1d872013-01-03 21:21:29 -08001436/* This function init rx port in firmware which in turn enables to receive data
1437 * from device before transmitting any packet.
1438 */
1439static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
1440{
1441 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001442 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Avinash Patilca8f2112013-02-08 18:18:09 -08001443 int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
Avinash Patilc6d1d872013-01-03 21:21:29 -08001444
Avinash Patildd04e6a2013-02-08 18:18:06 -08001445 /* Write the RX ring read pointer in to reg->rx_rdptr */
Avinash Patilca8f2112013-02-08 18:18:09 -08001446 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
1447 tx_wrap)) {
Avinash Patilc6d1d872013-01-03 21:21:29 -08001448 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001449 "RECV DATA: failed to write reg->rx_rdptr\n");
Avinash Patilc6d1d872013-01-03 21:21:29 -08001450 return -1;
1451 }
1452 return 0;
1453}
1454
1455/* This function downloads commands to the device
Amitkumar Karward930fae2011-10-11 17:41:21 -07001456 */
1457static int
1458mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1459{
1460 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001461 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001462 int ret = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001463 dma_addr_t cmd_buf_pa, cmdrsp_buf_pa;
1464 u8 *payload = (u8 *)skb->data;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001465
1466 if (!(skb->data && skb->len)) {
1467 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001468 __func__, skb->data, skb->len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001469 return -1;
1470 }
1471
1472 /* Make sure a command response buffer is available */
1473 if (!card->cmdrsp_buf) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001474 dev_err(adapter->dev,
1475 "No response buffer available, send command failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001476 return -EBUSY;
1477 }
1478
Avinash Patilfc331462013-01-03 21:21:30 -08001479 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1480 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001481
1482 adapter->cmd_sent = true;
Avinash Patilfc331462013-01-03 21:21:30 -08001483
1484 *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len);
1485 *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD);
1486
1487 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1488 return -1;
1489
1490 card->cmd_buf = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001491
1492 /* To send a command, the driver will:
1493 1. Write the 64bit physical address of the data buffer to
Avinash Patildd04e6a2013-02-08 18:18:06 -08001494 cmd response address low + cmd response address high
Amitkumar Karward930fae2011-10-11 17:41:21 -07001495 2. Ring the door bell (i.e. set the door bell interrupt)
1496
1497 In response to door bell interrupt, the firmware will perform
1498 the DMA of the command packet (first header to obtain the total
1499 length and then rest of the command).
1500 */
1501
1502 if (card->cmdrsp_buf) {
Aaron Durbindbccc922014-02-07 16:25:50 -08001503 cmdrsp_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmdrsp_buf);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001504 /* Write the lower 32bits of the cmdrsp buffer physical
1505 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001506 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo,
Avinash Patilfc331462013-01-03 21:21:30 -08001507 (u32)cmdrsp_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001508 dev_err(adapter->dev,
1509 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001510 ret = -1;
1511 goto done;
1512 }
1513 /* Write the upper 32bits of the cmdrsp buffer physical
1514 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001515 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001516 (u32)((u64)cmdrsp_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001517 dev_err(adapter->dev,
1518 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001519 ret = -1;
1520 goto done;
1521 }
1522 }
1523
Aaron Durbindbccc922014-02-07 16:25:50 -08001524 cmd_buf_pa = MWIFIEX_SKB_DMA_ADDR(card->cmd_buf);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001525 /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */
1526 if (mwifiex_write_reg(adapter, reg->cmd_addr_lo,
1527 (u32)cmd_buf_pa)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001528 dev_err(adapter->dev,
1529 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001530 ret = -1;
1531 goto done;
1532 }
Avinash Patildd04e6a2013-02-08 18:18:06 -08001533 /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */
1534 if (mwifiex_write_reg(adapter, reg->cmd_addr_hi,
Avinash Patilfc331462013-01-03 21:21:30 -08001535 (u32)((u64)cmd_buf_pa >> 32))) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001536 dev_err(adapter->dev,
1537 "Failed to write download cmd to boot code.\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001538 ret = -1;
1539 goto done;
1540 }
1541
Avinash Patildd04e6a2013-02-08 18:18:06 -08001542 /* Write the command length to reg->cmd_size */
1543 if (mwifiex_write_reg(adapter, reg->cmd_size,
1544 card->cmd_buf->len)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001545 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001546 "Failed to write cmd len to reg->cmd_size\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001547 ret = -1;
1548 goto done;
1549 }
1550
1551 /* Ring the door bell */
1552 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1553 CPU_INTR_DOOR_BELL)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001554 dev_err(adapter->dev,
1555 "Failed to assert door-bell intr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001556 ret = -1;
1557 goto done;
1558 }
1559
1560done:
1561 if (ret)
1562 adapter->cmd_sent = false;
1563
1564 return 0;
1565}
1566
1567/*
1568 * This function handles command complete interrupt
1569 */
1570static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1571{
1572 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001573 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001574 struct sk_buff *skb = card->cmdrsp_buf;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001575 int count = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001576 u16 rx_len;
1577 __le16 pkt_len;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001578
1579 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1580
Aaron Durbindbccc922014-02-07 16:25:50 -08001581 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001582
Aaron Durbin189b3292014-02-07 16:25:51 -08001583 /* Unmap the command as a response has been received. */
1584 if (card->cmd_buf) {
1585 mwifiex_unmap_pci_memory(adapter, card->cmd_buf,
1586 PCI_DMA_TODEVICE);
1587 card->cmd_buf = NULL;
1588 }
1589
Avinash Patilfc331462013-01-03 21:21:30 -08001590 pkt_len = *((__le16 *)skb->data);
1591 rx_len = le16_to_cpu(pkt_len);
1592 skb_trim(skb, rx_len);
1593 skb_pull(skb, INTF_HEADER_LEN);
1594
Amitkumar Karward930fae2011-10-11 17:41:21 -07001595 if (!adapter->curr_cmd) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001596 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001597 mwifiex_process_sleep_confirm_resp(adapter, skb->data,
1598 skb->len);
Amitkumar Karwar1c975602014-02-18 15:41:56 -08001599 mwifiex_pcie_enable_host_int(adapter);
1600 if (mwifiex_write_reg(adapter,
1601 PCIE_CPU_INT_EVENT,
1602 CPU_INTR_SLEEP_CFM_DONE)) {
1603 dev_warn(adapter->dev,
1604 "Write register failed\n");
1605 return -1;
1606 }
Avinash Patilc4bc9802014-03-18 22:19:17 -07001607 mwifiex_delay_for_sleep_cookie(adapter,
1608 MWIFIEX_MAX_DELAY_COUNT);
Avinash Patil52301a82013-02-12 14:38:32 -08001609 while (reg->sleep_cookie && (count++ < 10) &&
1610 mwifiex_pcie_ok_to_access_hw(adapter))
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001611 usleep_range(50, 60);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001612 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001613 dev_err(adapter->dev,
1614 "There is no command but got cmdrsp\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001615 }
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001616 memcpy(adapter->upld_buf, skb->data,
1617 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
Avinash Patil0f49d642013-03-20 17:56:23 -07001618 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001619 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1620 PCI_DMA_FROMDEVICE))
1621 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001622 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001623 adapter->curr_cmd->resp_skb = skb;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001624 adapter->cmd_resp_received = true;
1625 /* Take the pointer and set it to CMD node and will
1626 return in the response complete callback */
1627 card->cmdrsp_buf = NULL;
1628
1629 /* Clear the cmd-rsp buffer address in scratch registers. This
1630 will prevent firmware from writing to the same response
1631 buffer again. */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001632 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001633 dev_err(adapter->dev,
1634 "cmd_done: failed to clear cmd_rsp_addr_lo\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001635 return -1;
1636 }
1637 /* Write the upper 32bits of the cmdrsp buffer physical
1638 address */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001639 if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001640 dev_err(adapter->dev,
1641 "cmd_done: failed to clear cmd_rsp_addr_hi\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001642 return -1;
1643 }
1644 }
1645
1646 return 0;
1647}
1648
1649/*
1650 * Command Response processing complete handler
1651 */
1652static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1653 struct sk_buff *skb)
1654{
1655 struct pcie_service_card *card = adapter->card;
1656
1657 if (skb) {
1658 card->cmdrsp_buf = skb;
1659 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001660 if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
1661 PCI_DMA_FROMDEVICE))
1662 return -1;
1663 }
1664
Amitkumar Karward930fae2011-10-11 17:41:21 -07001665 return 0;
1666}
1667
1668/*
1669 * This function handles firmware event ready interrupt
1670 */
1671static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1672{
1673 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001674 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001675 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1676 u32 wrptr, event;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001677 struct mwifiex_evt_buf_desc *desc;
Avinash Patilfc331462013-01-03 21:21:30 -08001678
1679 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1680 mwifiex_pm_wakeup_card(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001681
1682 if (adapter->event_received) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001683 dev_dbg(adapter->dev, "info: Event being processed, "
1684 "do not process this interrupt just yet\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001685 return 0;
1686 }
1687
1688 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1689 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1690 return -1;
1691 }
1692
1693 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001694 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001695 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001696 "EventReady: failed to read reg->evt_wrptr\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001697 return -1;
1698 }
1699
1700 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001701 card->evtbd_rdptr, wrptr);
1702 if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
1703 & MWIFIEX_EVTBD_MASK)) ||
Avinash Patildd04e6a2013-02-08 18:18:06 -08001704 ((wrptr & reg->evt_rollover_ind) ==
1705 (card->evtbd_rdptr & reg->evt_rollover_ind))) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001706 struct sk_buff *skb_cmd;
1707 __le16 data_len = 0;
1708 u16 evt_len;
1709
1710 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1711 skb_cmd = card->evt_buf_list[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001712 mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001713
Amitkumar Karward930fae2011-10-11 17:41:21 -07001714 /* Take the pointer and set it to event pointer in adapter
1715 and will return back after event handling callback */
1716 card->evt_buf_list[rdptr] = NULL;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001717 desc = card->evtbd_ring[rdptr];
1718 memset(desc, 0, sizeof(*desc));
Amitkumar Karward930fae2011-10-11 17:41:21 -07001719
1720 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1721 adapter->event_cause = event;
1722 /* The first 4bytes will be the event transfer header
1723 len is 2 bytes followed by type which is 2 bytes */
1724 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1725 evt_len = le16_to_cpu(data_len);
1726
1727 skb_pull(skb_cmd, INTF_HEADER_LEN);
1728 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1729
1730 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1731 memcpy(adapter->event_body, skb_cmd->data +
1732 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1733 MWIFIEX_EVENT_HEADER_LEN);
1734
1735 adapter->event_received = true;
1736 adapter->event_skb = skb_cmd;
1737
1738 /* Do not update the event read pointer here, wait till the
1739 buffer is released. This is just to make things simpler,
1740 we need to find a better method of managing these buffers.
1741 */
Avinash Patil2703a662014-09-12 20:08:49 +05301742 } else {
1743 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1744 CPU_INTR_EVENT_DONE)) {
1745 dev_warn(adapter->dev,
1746 "Write register failed\n");
1747 return -1;
1748 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001749 }
1750
1751 return 0;
1752}
1753
1754/*
1755 * Event processing complete handler
1756 */
1757static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1758 struct sk_buff *skb)
1759{
1760 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001761 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001762 int ret = 0;
1763 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1764 u32 wrptr;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001765 struct mwifiex_evt_buf_desc *desc;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001766
1767 if (!skb)
1768 return 0;
1769
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001770 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001771 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001772 rdptr);
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001773 return -EINVAL;
Dan Carpenter1eb54c82011-11-07 19:31:47 -08001774 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001775
1776 /* Read the event ring write pointer set by firmware */
Avinash Patildd04e6a2013-02-08 18:18:06 -08001777 if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001778 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001779 "event_complete: failed to read reg->evt_wrptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001780 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001781 }
1782
1783 if (!card->evt_buf_list[rdptr]) {
1784 skb_push(skb, INTF_HEADER_LEN);
Avinash Patilfc331462013-01-03 21:21:30 -08001785 if (mwifiex_map_pci_memory(adapter, skb,
1786 MAX_EVENT_SIZE,
1787 PCI_DMA_FROMDEVICE))
1788 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001789 card->evt_buf_list[rdptr] = skb;
Avinash Patile05dc3e2013-02-08 18:18:08 -08001790 desc = card->evtbd_ring[rdptr];
Aaron Durbindbccc922014-02-07 16:25:50 -08001791 desc->paddr = MWIFIEX_SKB_DMA_ADDR(skb);
Avinash Patile05dc3e2013-02-08 18:18:08 -08001792 desc->len = (u16)skb->len;
1793 desc->flags = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001794 skb = NULL;
1795 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001796 dev_dbg(adapter->dev,
1797 "info: ERROR: buf still valid at index %d, <%p, %p>\n",
1798 rdptr, card->evt_buf_list[rdptr], skb);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001799 }
1800
1801 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1802 card->evtbd_rdptr = ((card->evtbd_rdptr &
Avinash Patildd04e6a2013-02-08 18:18:06 -08001803 reg->evt_rollover_ind) ^
1804 reg->evt_rollover_ind);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001805 }
1806
1807 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001808 card->evtbd_rdptr, wrptr);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001809
Avinash Patildd04e6a2013-02-08 18:18:06 -08001810 /* Write the event ring read pointer in to reg->evt_rdptr */
1811 if (mwifiex_write_reg(adapter, reg->evt_rdptr,
1812 card->evtbd_rdptr)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001813 dev_err(adapter->dev,
Avinash Patildd04e6a2013-02-08 18:18:06 -08001814 "event_complete: failed to read reg->evt_rdptr\n");
Amitkumar Karwar8c53e422011-12-08 20:41:03 -08001815 return -1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001816 }
1817
Amitkumar Karward930fae2011-10-11 17:41:21 -07001818 dev_dbg(adapter->dev, "info: Check Events Again\n");
1819 ret = mwifiex_pcie_process_event_ready(adapter);
1820
1821 return ret;
1822}
1823
1824/*
1825 * This function downloads the firmware to the card.
1826 *
1827 * Firmware is downloaded to the card in blocks. Every block download
1828 * is tested for CRC errors, and retried a number of times before
1829 * returning failure.
1830 */
1831static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1832 struct mwifiex_fw_image *fw)
1833{
1834 int ret;
1835 u8 *firmware = fw->fw_buf;
1836 u32 firmware_len = fw->fw_len;
1837 u32 offset = 0;
1838 struct sk_buff *skb;
1839 u32 txlen, tx_blocks = 0, tries, len;
1840 u32 block_retry_cnt = 0;
Avinash Patilfc331462013-01-03 21:21:30 -08001841 struct pcie_service_card *card = adapter->card;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001842 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001843
1844 if (!firmware || !firmware_len) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001845 dev_err(adapter->dev,
1846 "No firmware image found! Terminating download\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001847 return -1;
1848 }
1849
1850 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001851 firmware_len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001852
1853 if (mwifiex_pcie_disable_host_int(adapter)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001854 dev_err(adapter->dev,
1855 "%s: Disabling interrupts failed.\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001856 return -1;
1857 }
1858
1859 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1860 if (!skb) {
1861 ret = -ENOMEM;
1862 goto done;
1863 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07001864
1865 /* Perform firmware data transfer */
1866 do {
1867 u32 ireg_intr = 0;
1868
1869 /* More data? */
1870 if (offset >= firmware_len)
1871 break;
1872
1873 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001874 ret = mwifiex_read_reg(adapter, reg->cmd_size,
Amitkumar Karward930fae2011-10-11 17:41:21 -07001875 &len);
1876 if (ret) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001877 dev_warn(adapter->dev,
1878 "Failed reading len from boot code\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001879 goto done;
1880 }
1881 if (len)
1882 break;
Yogesh Ashok Poware7891ba2012-03-12 19:35:11 -07001883 usleep_range(10, 20);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001884 }
1885
1886 if (!len) {
1887 break;
1888 } else if (len > MWIFIEX_UPLD_SIZE) {
1889 pr_err("FW download failure @ %d, invalid length %d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001890 offset, len);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001891 ret = -1;
1892 goto done;
1893 }
1894
1895 txlen = len;
1896
1897 if (len & BIT(0)) {
1898 block_retry_cnt++;
1899 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1900 pr_err("FW download failure @ %d, over max "
1901 "retry count\n", offset);
1902 ret = -1;
1903 goto done;
1904 }
1905 dev_err(adapter->dev, "FW CRC error indicated by the "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001906 "helper: len = 0x%04X, txlen = %d\n",
1907 len, txlen);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001908 len &= ~BIT(0);
1909 /* Setting this to 0 to resend from same offset */
1910 txlen = 0;
1911 } else {
1912 block_retry_cnt = 0;
1913 /* Set blocksize to transfer - checking for
1914 last block */
1915 if (firmware_len - offset < txlen)
1916 txlen = firmware_len - offset;
1917
1918 dev_dbg(adapter->dev, ".");
1919
Avinash Patildd04e6a2013-02-08 18:18:06 -08001920 tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) /
1921 card->pcie.blksz_fw_dl;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001922
1923 /* Copy payload to buffer */
1924 memmove(skb->data, &firmware[offset], txlen);
1925 }
1926
1927 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
Avinash Patildd04e6a2013-02-08 18:18:06 -08001928 skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001929
1930 /* Send the boot command to device */
1931 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001932 dev_err(adapter->dev,
1933 "Failed to send firmware download command\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001934 ret = -1;
1935 goto done;
1936 }
Avinash Patilfc331462013-01-03 21:21:30 -08001937
Amitkumar Karward930fae2011-10-11 17:41:21 -07001938 /* Wait for the command done interrupt */
1939 do {
1940 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1941 &ireg_intr)) {
1942 dev_err(adapter->dev, "%s: Failed to read "
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001943 "interrupt status during fw dnld.\n",
1944 __func__);
Aaron Durbindbccc922014-02-07 16:25:50 -08001945 mwifiex_unmap_pci_memory(adapter, skb,
1946 PCI_DMA_TODEVICE);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001947 ret = -1;
1948 goto done;
1949 }
1950 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1951 CPU_INTR_DOOR_BELL);
Avinash Patilfc331462013-01-03 21:21:30 -08001952
Aaron Durbindbccc922014-02-07 16:25:50 -08001953 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
Avinash Patilfc331462013-01-03 21:21:30 -08001954
Amitkumar Karward930fae2011-10-11 17:41:21 -07001955 offset += txlen;
1956 } while (true);
1957
Amitkumar Karwarca5b20e2014-12-31 02:36:44 -08001958 dev_notice(adapter->dev,
1959 "info: FW download over, size %d bytes\n", offset);
Amitkumar Karward930fae2011-10-11 17:41:21 -07001960
1961 ret = 0;
1962
1963done:
1964 dev_kfree_skb_any(skb);
1965 return ret;
1966}
1967
1968/*
1969 * This function checks the firmware status in card.
1970 *
1971 * The winner interface is also determined by this function.
1972 */
1973static int
1974mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1975{
1976 int ret = 0;
1977 u32 firmware_stat, winner_status;
Avinash Patildd04e6a2013-02-08 18:18:06 -08001978 struct pcie_service_card *card = adapter->card;
1979 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07001980 u32 tries;
1981
1982 /* Mask spurios interrupts */
1983 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001984 HOST_INTR_MASK)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07001985 dev_warn(adapter->dev, "Write register failed\n");
1986 return -1;
1987 }
1988
1989 dev_dbg(adapter->dev, "Setting driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08001990 if (mwifiex_write_reg(adapter, reg->drv_rdy,
1991 FIRMWARE_READY_PCIE)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07001992 dev_err(adapter->dev,
1993 "Failed to write driver ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07001994 return -1;
1995 }
1996
1997 /* Wait for firmware initialization event */
1998 for (tries = 0; tries < poll_num; tries++) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08001999 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002000 &firmware_stat))
2001 ret = -1;
2002 else
2003 ret = 0;
2004 if (ret)
2005 continue;
2006 if (firmware_stat == FIRMWARE_READY_PCIE) {
2007 ret = 0;
2008 break;
2009 } else {
Amitkumar Karwara76b20e2013-07-22 19:17:53 -07002010 msleep(100);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002011 ret = -1;
2012 }
2013 }
2014
2015 if (ret) {
Avinash Patildd04e6a2013-02-08 18:18:06 -08002016 if (mwifiex_read_reg(adapter, reg->fw_status,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002017 &winner_status))
2018 ret = -1;
2019 else if (!winner_status) {
2020 dev_err(adapter->dev, "PCI-E is the winner\n");
2021 adapter->winner = 1;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002022 } else {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002023 dev_err(adapter->dev,
2024 "PCI-E is not the winner <%#x,%d>, exit dnld\n",
2025 ret, adapter->winner);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002026 }
2027 }
2028
2029 return ret;
2030}
2031
2032/*
2033 * This function reads the interrupt status from card.
2034 */
2035static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
2036{
2037 u32 pcie_ireg;
2038 unsigned long flags;
2039
2040 if (!mwifiex_pcie_ok_to_access_hw(adapter))
2041 return;
2042
2043 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
2044 dev_warn(adapter->dev, "Read register failed\n");
2045 return;
2046 }
2047
2048 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2049
2050 mwifiex_pcie_disable_host_int(adapter);
2051
2052 /* Clear the pending interrupts */
2053 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
2054 ~pcie_ireg)) {
2055 dev_warn(adapter->dev, "Write register failed\n");
2056 return;
2057 }
2058 spin_lock_irqsave(&adapter->int_lock, flags);
2059 adapter->int_status |= pcie_ireg;
2060 spin_unlock_irqrestore(&adapter->int_lock, flags);
2061
Amitkumar Karwar1c975602014-02-18 15:41:56 -08002062 if (!adapter->pps_uapsd_mode &&
2063 adapter->ps_state == PS_STATE_SLEEP &&
2064 mwifiex_pcie_ok_to_access_hw(adapter)) {
Amitkumar Karward930fae2011-10-11 17:41:21 -07002065 /* Potentially for PCIe we could get other
2066 * interrupts like shared. Don't change power
2067 * state until cookie is set */
Avinash Patilc24d9922013-03-22 21:49:06 -07002068 adapter->ps_state = PS_STATE_AWAKE;
2069 adapter->pm_wakeup_fw_try = false;
Amitkumar Karwar46361872014-12-31 02:36:41 -08002070 del_timer(&adapter->wakeup_timer);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002071 }
2072 }
2073}
2074
2075/*
2076 * Interrupt handler for PCIe root port
2077 *
2078 * This function reads the interrupt status from firmware and assigns
2079 * the main process in workqueue which will handle the interrupt.
2080 */
2081static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2082{
2083 struct pci_dev *pdev = (struct pci_dev *)context;
2084 struct pcie_service_card *card;
2085 struct mwifiex_adapter *adapter;
2086
2087 if (!pdev) {
2088 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
2089 goto exit;
2090 }
2091
Jingoo Hanb2a31202013-09-09 14:26:51 +09002092 card = pci_get_drvdata(pdev);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002093 if (!card || !card->adapter) {
2094 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002095 card ? card->adapter : NULL);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002096 goto exit;
2097 }
2098 adapter = card->adapter;
2099
2100 if (adapter->surprise_removed)
2101 goto exit;
2102
2103 mwifiex_interrupt_status(adapter);
Shengzhen Lib2713f62015-03-13 17:37:54 +05302104 mwifiex_queue_main_work(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002105
2106exit:
2107 return IRQ_HANDLED;
2108}
2109
2110/*
2111 * This function checks the current interrupt status.
2112 *
2113 * The following interrupts are checked and handled by this function -
2114 * - Data sent
2115 * - Command sent
2116 * - Command received
2117 * - Packets received
2118 * - Events received
2119 *
2120 * In case of Rx packets received, the packets are uploaded from card to
2121 * host and processed accordingly.
2122 */
2123static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
2124{
2125 int ret;
Avinash Patil659c4782013-01-03 21:21:28 -08002126 u32 pcie_ireg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002127 unsigned long flags;
2128
2129 spin_lock_irqsave(&adapter->int_lock, flags);
2130 /* Clear out unused interrupts */
Avinash Patil659c4782013-01-03 21:21:28 -08002131 pcie_ireg = adapter->int_status;
2132 adapter->int_status = 0;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002133 spin_unlock_irqrestore(&adapter->int_lock, flags);
2134
Avinash Patil659c4782013-01-03 21:21:28 -08002135 while (pcie_ireg & HOST_INTR_MASK) {
2136 if (pcie_ireg & HOST_INTR_DNLD_DONE) {
2137 pcie_ireg &= ~HOST_INTR_DNLD_DONE;
Avinash Patile7f767a2013-01-03 21:21:32 -08002138 dev_dbg(adapter->dev, "info: TX DNLD Done\n");
2139 ret = mwifiex_pcie_send_data_complete(adapter);
2140 if (ret)
2141 return ret;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002142 }
Avinash Patil659c4782013-01-03 21:21:28 -08002143 if (pcie_ireg & HOST_INTR_UPLD_RDY) {
2144 pcie_ireg &= ~HOST_INTR_UPLD_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002145 dev_dbg(adapter->dev, "info: Rx DATA\n");
2146 ret = mwifiex_pcie_process_recv_data(adapter);
2147 if (ret)
2148 return ret;
2149 }
Avinash Patil659c4782013-01-03 21:21:28 -08002150 if (pcie_ireg & HOST_INTR_EVENT_RDY) {
2151 pcie_ireg &= ~HOST_INTR_EVENT_RDY;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002152 dev_dbg(adapter->dev, "info: Rx EVENT\n");
2153 ret = mwifiex_pcie_process_event_ready(adapter);
2154 if (ret)
2155 return ret;
2156 }
2157
Avinash Patil659c4782013-01-03 21:21:28 -08002158 if (pcie_ireg & HOST_INTR_CMD_DONE) {
2159 pcie_ireg &= ~HOST_INTR_CMD_DONE;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002160 if (adapter->cmd_sent) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002161 dev_dbg(adapter->dev,
2162 "info: CMD sent Interrupt\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002163 adapter->cmd_sent = false;
2164 }
2165 /* Handle command response */
2166 ret = mwifiex_pcie_process_cmd_complete(adapter);
2167 if (ret)
2168 return ret;
2169 }
2170
2171 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
2172 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
2173 &pcie_ireg)) {
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002174 dev_warn(adapter->dev,
2175 "Read register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002176 return -1;
2177 }
2178
2179 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
2180 if (mwifiex_write_reg(adapter,
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002181 PCIE_HOST_INT_STATUS,
2182 ~pcie_ireg)) {
2183 dev_warn(adapter->dev,
2184 "Write register failed\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002185 return -1;
2186 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002187 }
2188
2189 }
2190 }
2191 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002192 adapter->cmd_sent, adapter->data_sent);
Avinash Patilb2fda1f2013-03-22 21:49:05 -07002193 if (adapter->ps_state != PS_STATE_SLEEP)
2194 mwifiex_pcie_enable_host_int(adapter);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002195
2196 return 0;
2197}
2198
2199/*
2200 * This function downloads data from driver to card.
2201 *
2202 * Both commands and data packets are transferred to the card by this
2203 * function.
2204 *
2205 * This function adds the PCIE specific header to the front of the buffer
2206 * before transferring. The header contains the length of the packet and
2207 * the type. The firmware handles the packets based upon this set type.
2208 */
2209static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2210 struct sk_buff *skb,
2211 struct mwifiex_tx_param *tx_param)
2212{
Dan Carpenterfa161cb2011-11-07 19:31:45 -08002213 if (!skb) {
2214 dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002215 return -1;
2216 }
2217
2218 if (type == MWIFIEX_TYPE_DATA)
Avinash Patile7f767a2013-01-03 21:21:32 -08002219 return mwifiex_pcie_send_data(adapter, skb, tx_param);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002220 else if (type == MWIFIEX_TYPE_CMD)
2221 return mwifiex_pcie_send_cmd(adapter, skb);
2222
2223 return 0;
2224}
2225
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002226/* This function read/write firmware */
2227static enum rdwr_status
2228mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2229{
2230 int ret, tries;
2231 u8 ctrl_data;
2232 struct pcie_service_card *card = adapter->card;
2233 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2234
2235 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
2236 if (ret) {
2237 dev_err(adapter->dev, "PCIE write err\n");
2238 return RDWR_STATUS_FAILURE;
2239 }
2240
2241 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2242 mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
2243 if (ctrl_data == FW_DUMP_DONE)
2244 return RDWR_STATUS_SUCCESS;
2245 if (doneflag && ctrl_data == doneflag)
2246 return RDWR_STATUS_DONE;
2247 if (ctrl_data != FW_DUMP_HOST_READY) {
2248 dev_info(adapter->dev,
2249 "The ctrl reg was changed, re-try again!\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002250 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2251 FW_DUMP_HOST_READY);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002252 if (ret) {
2253 dev_err(adapter->dev, "PCIE write err\n");
2254 return RDWR_STATUS_FAILURE;
2255 }
2256 }
2257 usleep_range(100, 200);
2258 }
2259
2260 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2261 return RDWR_STATUS_FAILURE;
2262}
2263
2264/* This function dump firmware memory to file */
2265static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2266{
2267 struct pcie_service_card *card = adapter->card;
2268 const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
2269 unsigned int reg, reg_start, reg_end;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002270 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2271 enum rdwr_status stat;
2272 u32 memory_size;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002273 int ret;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002274 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2275
Avinash Patilb4e8aeb2015-02-11 23:12:26 +05302276 if (!card->pcie.can_dump_fw)
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002277 return;
2278
2279 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2280 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2281
2282 if (entry->mem_ptr) {
2283 vfree(entry->mem_ptr);
2284 entry->mem_ptr = NULL;
2285 }
2286 entry->mem_size = 0;
2287 }
2288
Bing Zhao1d9e9542014-07-17 15:55:09 -07002289 dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002290
2291 /* Read the number of the memories which will dump */
2292 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2293 if (stat == RDWR_STATUS_FAILURE)
2294 goto done;
2295
2296 reg = creg->fw_dump_start;
2297 mwifiex_read_reg_byte(adapter, reg, &dump_num);
2298
2299 /* Read the length of every memory which will dump */
2300 for (idx = 0; idx < dump_num; idx++) {
2301 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2302
2303 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2304 if (stat == RDWR_STATUS_FAILURE)
2305 goto done;
2306
2307 memory_size = 0;
2308 reg = creg->fw_dump_start;
2309 for (i = 0; i < 4; i++) {
2310 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2311 memory_size |= (read_reg << (i * 8));
2312 reg++;
2313 }
2314
2315 if (memory_size == 0) {
2316 dev_info(adapter->dev, "Firmware dump Finished!\n");
Amitkumar Karwar7e174832014-09-18 07:18:50 -04002317 ret = mwifiex_write_reg(adapter, creg->fw_dump_ctrl,
2318 FW_DUMP_READ_DONE);
2319 if (ret) {
2320 dev_err(adapter->dev, "PCIE write err\n");
2321 goto done;
2322 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002323 break;
2324 }
2325
2326 dev_info(adapter->dev,
2327 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2328 entry->mem_ptr = vmalloc(memory_size + 1);
2329 entry->mem_size = memory_size;
2330 if (!entry->mem_ptr) {
2331 dev_err(adapter->dev,
2332 "Vmalloc %s failed\n", entry->mem_name);
2333 goto done;
2334 }
2335 dbg_ptr = entry->mem_ptr;
2336 end_ptr = dbg_ptr + memory_size;
2337
2338 doneflag = entry->done_flag;
Bing Zhao1d9e9542014-07-17 15:55:09 -07002339 dev_info(adapter->dev, "Start %s output, please wait...\n",
2340 entry->mem_name);
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002341
2342 do {
2343 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2344 if (RDWR_STATUS_FAILURE == stat)
2345 goto done;
2346
2347 reg_start = creg->fw_dump_start;
2348 reg_end = creg->fw_dump_end;
2349 for (reg = reg_start; reg <= reg_end; reg++) {
2350 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
Amitkumar Karwar24716872014-09-18 08:04:01 -04002351 if (dbg_ptr < end_ptr) {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002352 dbg_ptr++;
Amitkumar Karwar24716872014-09-18 08:04:01 -04002353 } else {
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002354 dev_err(adapter->dev,
2355 "Allocated buf not enough\n");
Amitkumar Karwar24716872014-09-18 08:04:01 -04002356 goto done;
2357 }
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002358 }
2359
2360 if (stat != RDWR_STATUS_DONE)
2361 continue;
2362
2363 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2364 entry->mem_name, dbg_ptr - entry->mem_ptr);
2365 break;
2366 } while (true);
2367 }
Bing Zhao1d9e9542014-07-17 15:55:09 -07002368 dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002369
2370 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2371
2372done:
2373 adapter->curr_mem_idx = 0;
2374}
2375
2376static void mwifiex_pcie_work(struct work_struct *work)
2377{
2378 struct mwifiex_adapter *adapter =
2379 container_of(work, struct mwifiex_adapter, iface_work);
2380
2381 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2382 &adapter->iface_work_flags))
2383 mwifiex_pcie_fw_dump_work(adapter);
2384}
2385
2386/* This function dumps FW information */
2387static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2388{
2389 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
2390 return;
2391
2392 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
2393
2394 schedule_work(&adapter->iface_work);
2395}
2396
Amitkumar Karward930fae2011-10-11 17:41:21 -07002397/*
2398 * This function initializes the PCI-E host memory space, WCB rings, etc.
2399 *
2400 * The following initializations steps are followed -
2401 * - Allocate TXBD ring buffers
2402 * - Allocate RXBD ring buffers
2403 * - Allocate event BD ring buffers
2404 * - Allocate command response ring buffer
2405 * - Allocate sleep cookie buffer
2406 */
2407static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
2408{
2409 struct pcie_service_card *card = adapter->card;
2410 int ret;
2411 struct pci_dev *pdev = card->dev;
Avinash Patil52301a82013-02-12 14:38:32 -08002412 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002413
2414 pci_set_drvdata(pdev, card);
2415
2416 ret = pci_enable_device(pdev);
2417 if (ret)
2418 goto err_enable_dev;
2419
2420 pci_set_master(pdev);
2421
2422 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
2423 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2424 if (ret) {
2425 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
2426 goto err_set_dma_mask;
2427 }
2428
2429 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2430 if (ret) {
2431 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
2432 goto err_set_dma_mask;
2433 }
2434
2435 ret = pci_request_region(pdev, 0, DRV_NAME);
2436 if (ret) {
2437 dev_err(adapter->dev, "req_reg(0) error\n");
2438 goto err_req_region0;
2439 }
2440 card->pci_mmap = pci_iomap(pdev, 0, 0);
2441 if (!card->pci_mmap) {
2442 dev_err(adapter->dev, "iomap(0) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002443 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002444 goto err_iomap0;
2445 }
2446 ret = pci_request_region(pdev, 2, DRV_NAME);
2447 if (ret) {
2448 dev_err(adapter->dev, "req_reg(2) error\n");
2449 goto err_req_region2;
2450 }
2451 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
2452 if (!card->pci_mmap1) {
2453 dev_err(adapter->dev, "iomap(2) error\n");
Alexey Khoroshilov32207122013-01-26 00:56:03 +04002454 ret = -EIO;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002455 goto err_iomap2;
2456 }
2457
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002458 dev_dbg(adapter->dev,
2459 "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
2460 card->pci_mmap, card->pci_mmap1);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002461
2462 card->cmdrsp_buf = NULL;
2463 ret = mwifiex_pcie_create_txbd_ring(adapter);
2464 if (ret)
2465 goto err_cre_txbd;
2466 ret = mwifiex_pcie_create_rxbd_ring(adapter);
2467 if (ret)
2468 goto err_cre_rxbd;
2469 ret = mwifiex_pcie_create_evtbd_ring(adapter);
2470 if (ret)
2471 goto err_cre_evtbd;
2472 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
2473 if (ret)
2474 goto err_alloc_cmdbuf;
Avinash Patil52301a82013-02-12 14:38:32 -08002475 if (reg->sleep_cookie) {
2476 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
2477 if (ret)
2478 goto err_alloc_cookie;
2479 } else {
2480 card->sleep_cookie_vbase = NULL;
2481 }
Amitkumar Karward930fae2011-10-11 17:41:21 -07002482 return ret;
2483
2484err_alloc_cookie:
2485 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2486err_alloc_cmdbuf:
2487 mwifiex_pcie_delete_evtbd_ring(adapter);
2488err_cre_evtbd:
2489 mwifiex_pcie_delete_rxbd_ring(adapter);
2490err_cre_rxbd:
2491 mwifiex_pcie_delete_txbd_ring(adapter);
2492err_cre_txbd:
2493 pci_iounmap(pdev, card->pci_mmap1);
2494err_iomap2:
2495 pci_release_region(pdev, 2);
2496err_req_region2:
2497 pci_iounmap(pdev, card->pci_mmap);
2498err_iomap0:
2499 pci_release_region(pdev, 0);
2500err_req_region0:
2501err_set_dma_mask:
2502 pci_disable_device(pdev);
2503err_enable_dev:
2504 pci_set_drvdata(pdev, NULL);
2505 return ret;
2506}
2507
2508/*
2509 * This function cleans up the allocated card buffers.
2510 *
2511 * The following are freed by this function -
2512 * - TXBD ring buffers
2513 * - RXBD ring buffers
2514 * - Event BD ring buffers
2515 * - Command response ring buffer
2516 * - Sleep cookie buffer
2517 */
2518static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
2519{
2520 struct pcie_service_card *card = adapter->card;
2521 struct pci_dev *pdev = card->dev;
Avinash Patildd04e6a2013-02-08 18:18:06 -08002522 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002523
Amitkumar Karward930fae2011-10-11 17:41:21 -07002524 if (user_rmmod) {
Avinash Patilfc331462013-01-03 21:21:30 -08002525 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
Avinash Patildd04e6a2013-02-08 18:18:06 -08002526 if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
Yogesh Ashok Powarf57c1ed2012-03-13 19:22:37 -07002527 dev_err(adapter->dev,
2528 "Failed to write driver not-ready signature\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002529 }
2530
2531 if (pdev) {
2532 pci_iounmap(pdev, card->pci_mmap);
2533 pci_iounmap(pdev, card->pci_mmap1);
Yogesh Ashok Powar5b0d9b22013-04-23 16:49:48 -07002534 pci_disable_device(pdev);
Yogesh Ashok Powarc380aaf2013-04-23 16:49:47 -07002535 pci_release_region(pdev, 2);
2536 pci_release_region(pdev, 0);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002537 pci_set_drvdata(pdev, NULL);
2538 }
Amitkumar Karwar3c59e322013-11-14 19:10:41 -08002539 kfree(card);
Amitkumar Karward930fae2011-10-11 17:41:21 -07002540}
2541
2542/*
2543 * This function registers the PCIE device.
2544 *
2545 * PCIE IRQ is claimed, block size is set and driver data is initialized.
2546 */
2547static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2548{
2549 int ret;
2550 struct pcie_service_card *card = adapter->card;
2551 struct pci_dev *pdev = card->dev;
2552
2553 /* save adapter pointer in card */
2554 card->adapter = adapter;
2555
2556 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
2557 "MRVL_PCIE", pdev);
2558 if (ret) {
2559 pr_err("request_irq failed: ret=%d\n", ret);
2560 adapter->card = NULL;
2561 return -1;
2562 }
2563
2564 adapter->dev = &pdev->dev;
Amitkumar Karwar828cf222014-02-27 19:35:13 -08002565 adapter->tx_buf_size = card->pcie.tx_buf_size;
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002566 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
2567 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
Avinash Patildd04e6a2013-02-08 18:18:06 -08002568 strcpy(adapter->fw_name, card->pcie.firmware);
Avinash Patil1fe192d2015-01-23 17:09:19 +05302569 adapter->ext_scan = card->pcie.can_ext_scan;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002570
2571 return 0;
2572}
2573
2574/*
2575 * This function unregisters the PCIE device.
2576 *
2577 * The PCIE IRQ is released, the function is disabled and driver
2578 * data is set to null.
2579 */
2580static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
2581{
2582 struct pcie_service_card *card = adapter->card;
Avinash Patil52301a82013-02-12 14:38:32 -08002583 const struct mwifiex_pcie_card_reg *reg;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002584
2585 if (card) {
2586 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
2587 free_irq(card->dev->irq, card->dev);
Avinash Patilfc331462013-01-03 21:21:30 -08002588
Avinash Patil52301a82013-02-12 14:38:32 -08002589 reg = card->pcie.reg;
2590 if (reg->sleep_cookie)
2591 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
2592
Avinash Patilfc331462013-01-03 21:21:30 -08002593 mwifiex_pcie_delete_cmdrsp_buf(adapter);
2594 mwifiex_pcie_delete_evtbd_ring(adapter);
2595 mwifiex_pcie_delete_rxbd_ring(adapter);
2596 mwifiex_pcie_delete_txbd_ring(adapter);
2597 card->cmdrsp_buf = NULL;
Amitkumar Karward930fae2011-10-11 17:41:21 -07002598 }
2599}
2600
2601static struct mwifiex_if_ops pcie_ops = {
2602 .init_if = mwifiex_pcie_init,
2603 .cleanup_if = mwifiex_pcie_cleanup,
2604 .check_fw_status = mwifiex_check_fw_status,
2605 .prog_fw = mwifiex_prog_fw_w_helper,
2606 .register_dev = mwifiex_register_dev,
2607 .unregister_dev = mwifiex_unregister_dev,
2608 .enable_int = mwifiex_pcie_enable_host_int,
2609 .process_int_status = mwifiex_process_int_status,
2610 .host_to_card = mwifiex_pcie_host_to_card,
2611 .wakeup = mwifiex_pm_wakeup_card,
2612 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
2613
2614 /* PCIE specific */
2615 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
2616 .event_complete = mwifiex_pcie_event_complete,
2617 .update_mp_end_port = NULL,
2618 .cleanup_mpa_buf = NULL,
Avinash Patilc6d1d872013-01-03 21:21:29 -08002619 .init_fw_port = mwifiex_pcie_init_fw_port,
Avinash Patilfbd7e7a2013-01-03 21:21:31 -08002620 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
Amitkumar Karwar92c25382014-06-19 21:38:52 -07002621 .fw_dump = mwifiex_pcie_fw_dump,
2622 .iface_work = mwifiex_pcie_work,
Amitkumar Karward930fae2011-10-11 17:41:21 -07002623};
2624
2625/*
2626 * This function initializes the PCIE driver module.
2627 *
2628 * This initiates the semaphore and registers the device with
2629 * PCIE bus.
2630 */
2631static int mwifiex_pcie_init_module(void)
2632{
2633 int ret;
2634
Avinash Patilca8f2112013-02-08 18:18:09 -08002635 pr_debug("Marvell PCIe Driver\n");
Amitkumar Karward930fae2011-10-11 17:41:21 -07002636
2637 sema_init(&add_remove_card_sem, 1);
2638
2639 /* Clear the flag in case user removes the card. */
2640 user_rmmod = 0;
2641
2642 ret = pci_register_driver(&mwifiex_pcie);
2643 if (ret)
2644 pr_err("Driver register failed!\n");
2645 else
2646 pr_debug("info: Driver registered successfully!\n");
2647
2648 return ret;
2649}
2650
2651/*
2652 * This function cleans up the PCIE driver.
2653 *
2654 * The following major steps are followed for cleanup -
2655 * - Resume the device if its suspended
2656 * - Disconnect the device if connected
2657 * - Shutdown the firmware
2658 * - Unregister the device from PCIE bus.
2659 */
2660static void mwifiex_pcie_cleanup_module(void)
2661{
2662 if (!down_interruptible(&add_remove_card_sem))
2663 up(&add_remove_card_sem);
2664
2665 /* Set the flag as user is removing this module. */
2666 user_rmmod = 1;
2667
2668 pci_unregister_driver(&mwifiex_pcie);
2669}
2670
2671module_init(mwifiex_pcie_init_module);
2672module_exit(mwifiex_pcie_cleanup_module);
2673
2674MODULE_AUTHOR("Marvell International Ltd.");
2675MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
2676MODULE_VERSION(PCIE_VERSION);
2677MODULE_LICENSE("GPL v2");
Avinash Patilca8f2112013-02-08 18:18:09 -08002678MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME);
2679MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME);