aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c2
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h2
-rw-r--r--drivers/net/wireless/mwifiex/11h.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.c5
-rw-r--r--drivers/net/wireless/mwifiex/11n.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c29
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h2
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/README32
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c66
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h2
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c2
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c46
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c95
-rw-r--r--drivers/net/wireless/mwifiex/decl.h2
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c85
-rw-r--r--drivers/net/wireless/mwifiex/fw.h4
-rw-r--r--drivers/net/wireless/mwifiex/ie.c2
-rw-r--r--drivers/net/wireless/mwifiex/init.c15
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h2
-rw-r--r--drivers/net/wireless/mwifiex/join.c10
-rw-r--r--drivers/net/wireless/mwifiex/main.c24
-rw-r--r--drivers/net/wireless/mwifiex/main.h34
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c191
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h12
-rw-r--r--drivers/net/wireless/mwifiex/scan.c2
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c235
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h14
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c18
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c2
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c30
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c6
-rw-r--r--drivers/net/wireless/mwifiex/usb.c2
-rw-r--r--drivers/net/wireless/mwifiex/usb.h2
-rw-r--r--drivers/net/wireless/mwifiex/util.c2
-rw-r--r--drivers/net/wireless/mwifiex/util.h2
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c11
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h2
47 files changed, 831 insertions, 189 deletions
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index 706831df1fa2..59d23fb2365f 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11ac 2 * Marvell Wireless LAN device driver: 802.11ac
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
index 0b02cb6cfcb4..1ca92c7a8a4a 100644
--- a/drivers/net/wireless/mwifiex/11ac.h
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11ac 2 * Marvell Wireless LAN device driver: 802.11ac
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index e76b0db4e3e6..2668e83afbb6 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11h 2 * Marvell Wireless LAN device driver: 802.11h
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index e1c2f67ae85e..62f5dbe602d3 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n 2 * Marvell Wireless LAN device driver: 802.11n
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -541,7 +541,6 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
541int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) 541int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
542{ 542{
543 struct host_cmd_ds_11n_addba_req add_ba_req; 543 struct host_cmd_ds_11n_addba_req add_ba_req;
544 struct mwifiex_sta_node *sta_ptr;
545 u32 tx_win_size = priv->add_ba_param.tx_win_size; 544 u32 tx_win_size = priv->add_ba_param.tx_win_size;
546 static u8 dialog_tok; 545 static u8 dialog_tok;
547 int ret; 546 int ret;
@@ -553,6 +552,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
553 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && 552 ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
554 priv->adapter->is_hw_11ac_capable && 553 priv->adapter->is_hw_11ac_capable &&
555 memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) { 554 memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) {
555 struct mwifiex_sta_node *sta_ptr;
556
556 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac); 557 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
557 if (!sta_ptr) { 558 if (!sta_ptr) {
558 dev_warn(priv->adapter->dev, 559 dev_warn(priv->adapter->dev,
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 0b73fa08f5d4..2ee268b632be 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n 2 * Marvell Wireless LAN device driver: 802.11n
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index fe0f66f73507..8720a3d3c755 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n Aggregation 2 * Marvell Wireless LAN device driver: 802.11n Aggregation
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h
index 892098d6a696..0cd2a3eb6c17 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.h
+++ b/drivers/net/wireless/mwifiex/11n_aggr.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n Aggregation 2 * Marvell Wireless LAN device driver: 802.11n Aggregation
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 0c3571f830b0..06a2c215ef5e 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering 2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -249,13 +249,22 @@ void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
249 * buffered in Rx reordering table. 249 * buffered in Rx reordering table.
250 */ 250 */
251static int 251static int
252mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr) 252mwifiex_11n_find_last_seq_num(struct reorder_tmr_cnxt *ctx)
253{ 253{
254 struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr = ctx->ptr;
255 struct mwifiex_private *priv = ctx->priv;
256 unsigned long flags;
254 int i; 257 int i;
255 258
256 for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i) 259 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
257 if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) 260 for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i) {
261 if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) {
262 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
263 flags);
258 return i; 264 return i;
265 }
266 }
267 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
259 268
260 return -1; 269 return -1;
261} 270}
@@ -274,7 +283,7 @@ mwifiex_flush_data(unsigned long context)
274 (struct reorder_tmr_cnxt *) context; 283 (struct reorder_tmr_cnxt *) context;
275 int start_win, seq_num; 284 int start_win, seq_num;
276 285
277 seq_num = mwifiex_11n_find_last_seq_num(ctx->ptr); 286 seq_num = mwifiex_11n_find_last_seq_num(ctx);
278 287
279 if (seq_num < 0) 288 if (seq_num < 0)
280 return; 289 return;
@@ -729,9 +738,9 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
729 mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr); 738 mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
730 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); 739 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
731 } 740 }
741 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
732 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); 742 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
733 743
734 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
735 mwifiex_reset_11n_rx_seq_num(priv); 744 mwifiex_reset_11n_rx_seq_num(priv);
736} 745}
737 746
@@ -749,10 +758,14 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
749 priv = adapter->priv[i]; 758 priv = adapter->priv[i];
750 if (!priv) 759 if (!priv)
751 continue; 760 continue;
752 if (list_empty(&priv->rx_reorder_tbl_ptr))
753 continue;
754 761
755 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags); 762 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
763 if (list_empty(&priv->rx_reorder_tbl_ptr)) {
764 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
765 lock_flags);
766 continue;
767 }
768
756 list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) 769 list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
757 tbl->flags = flags; 770 tbl->flags = flags;
758 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags); 771 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 0fc76e4a60f8..3a87bb0e3a62 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering 2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 2aa208ffbe23..9487d728ac20 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -1,5 +1,5 @@
1# 1#
2# Copyright (C) 2011, Marvell International Ltd. 2# Copyright (C) 2011-2014, Marvell International Ltd.
3# 3#
4# This software file (the "File") is distributed by Marvell International 4# This software file (the "File") is distributed by Marvell International
5# Ltd. under the terms of the GNU General Public License Version 2, June 1991 5# Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 3b55ce5690a5..31928caeeed2 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -1,4 +1,4 @@
1# Copyright (C) 2011, Marvell International Ltd. 1# Copyright (C) 2011-2014, Marvell International Ltd.
2# 2#
3# This software file (the "File") is distributed by Marvell International 3# This software file (the "File") is distributed by Marvell International
4# Ltd. under the terms of the GNU General Public License Version 2, June 1991 4# Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -194,6 +194,36 @@ rdeeprom
194 Example: 194 Example:
195 echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0 195 echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0
196 196
197hscfg
198 This command is used to debug/simulate host sleep feature using
199 different configuration parameters.
200
201 Usage:
202 echo "<condition> [GPIO# [gap]]]" > hscfg
203 cat hscfg
204
205 where the parameters are,
206 <condition>: bit 0 = 1 -- broadcast data
207 bit 1 = 1 -- unicast data
208 bit 2 = 1 -- mac event
209 bit 3 = 1 -- multicast data
210 [GPIO#]: pin number of GPIO used to wakeup the host.
211 GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO
212 will be used instead).
213 [gap]: the gap in milliseconds between wakeup signal and
214 wakeup event or 0xff for special setting (host
215 acknowledge required) when GPIO is used to wakeup host.
216
217 Examples:
218 echo "-1" > hscfg : Cancel host sleep mode
219 echo "3" > hscfg : Broadcast and unicast data;
220 Use GPIO and gap set previously
221 echo "2 3" > hscfg : Unicast data and GPIO 3;
222 Use gap set previously
223 echo "2 1 160" > hscfg : Unicast data, GPIO 1 and gap 160 ms
224 echo "2 1 0xff" > hscfg : Unicast data, GPIO 1; Wait for host
225 to ack before sending wakeup event
226
197getlog 227getlog
198 This command is used to get the statistics available in the station. 228 This command is used to get the statistics available in the station.
199 Usage: 229 Usage:
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index b511613bba2d..e2e6bf13c2d8 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: CFG80211 2 * Marvell Wireless LAN device driver: CFG80211
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -42,36 +42,6 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
42 .beacon_int_infra_match = true, 42 .beacon_int_infra_match = true,
43}; 43};
44 44
45static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
46 .n_reg_rules = 7,
47 .alpha2 = "99",
48 .reg_rules = {
49 /* Channel 1 - 11 */
50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
51 /* Channel 12 - 13 */
52 REG_RULE(2467-10, 2472+10, 20, 3, 20,
53 NL80211_RRF_NO_IR),
54 /* Channel 14 */
55 REG_RULE(2484-10, 2484+10, 20, 3, 20,
56 NL80211_RRF_NO_IR |
57 NL80211_RRF_NO_OFDM),
58 /* Channel 36 - 48 */
59 REG_RULE(5180-10, 5240+10, 40, 3, 20,
60 NL80211_RRF_NO_IR),
61 /* Channel 149 - 165 */
62 REG_RULE(5745-10, 5825+10, 40, 3, 20,
63 NL80211_RRF_NO_IR),
64 /* Channel 52 - 64 */
65 REG_RULE(5260-10, 5320+10, 40, 3, 30,
66 NL80211_RRF_NO_IR |
67 NL80211_RRF_DFS),
68 /* Channel 100 - 140 */
69 REG_RULE(5500-10, 5700+10, 40, 3, 30,
70 NL80211_RRF_NO_IR |
71 NL80211_RRF_DFS),
72 }
73};
74
75/* 45/*
76 * This function maps the nl802.11 channel type into driver channel type. 46 * This function maps the nl802.11 channel type into driver channel type.
77 * 47 *
@@ -151,7 +121,6 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
151 u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 121 u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
152 u16 pkt_len; 122 u16 pkt_len;
153 u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT; 123 u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
154 struct timeval tv;
155 124
156 pkt_len = len + ETH_ALEN; 125 pkt_len = len + ETH_ALEN;
157 126
@@ -173,8 +142,7 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
173 len - sizeof(struct ieee80211_hdr_3addr)); 142 len - sizeof(struct ieee80211_hdr_3addr));
174 143
175 skb->priority = LOW_PRIO_TID; 144 skb->priority = LOW_PRIO_TID;
176 do_gettimeofday(&tv); 145 __net_timestamp(skb);
177 skb->tstamp = timeval_to_ktime(tv);
178 146
179 return 0; 147 return 0;
180} 148}
@@ -1636,9 +1604,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
1636 return -EINVAL; 1604 return -EINVAL;
1637 } 1605 }
1638 1606
1639 /* disconnect before try to associate */
1640 mwifiex_deauthenticate(priv, NULL);
1641
1642 /* As this is new association, clear locally stored 1607 /* As this is new association, clear locally stored
1643 * keys and security related flags */ 1608 * keys and security related flags */
1644 priv->sec_info.wpa_enabled = false; 1609 priv->sec_info.wpa_enabled = false;
@@ -1776,6 +1741,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1776 return -EINVAL; 1741 return -EINVAL;
1777 } 1742 }
1778 1743
1744 if (priv->wdev && priv->wdev->current_bss) {
1745 wiphy_warn(wiphy, "%s: already connected\n", dev->name);
1746 return -EALREADY;
1747 }
1748
1779 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 1749 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1780 (char *) sme->ssid, sme->bssid); 1750 (char *) sme->ssid, sme->bssid);
1781 1751
@@ -2264,7 +2234,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2264 } 2234 }
2265 2235
2266 dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, 2236 dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
2267 ether_setup, IEEE80211_NUM_ACS, 1); 2237 NET_NAME_UNKNOWN, ether_setup,
2238 IEEE80211_NUM_ACS, 1);
2268 if (!dev) { 2239 if (!dev) {
2269 wiphy_err(wiphy, "no memory available for netdevice\n"); 2240 wiphy_err(wiphy, "no memory available for netdevice\n");
2270 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2241 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -2484,6 +2455,16 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2484 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2455 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2485 if (filt_num) 2456 if (filt_num)
2486 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2457 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2458
2459 filt_num++;
2460 mef_entry->filter[filt_num].repeat = 16;
2461 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2462 ETH_ALEN);
2463 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2464 ETH_ALEN;
2465 mef_entry->filter[filt_num].offset = 56;
2466 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2467 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2487 } 2468 }
2488 2469
2489 if (!mef_cfg.criteria) 2470 if (!mef_cfg.criteria)
@@ -2632,7 +2613,8 @@ static int
2632mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, 2613mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2633 const u8 *peer, u8 action_code, u8 dialog_token, 2614 const u8 *peer, u8 action_code, u8 dialog_token,
2634 u16 status_code, u32 peer_capability, 2615 u16 status_code, u32 peer_capability,
2635 const u8 *extra_ies, size_t extra_ies_len) 2616 bool initiator, const u8 *extra_ies,
2617 size_t extra_ies_len)
2636{ 2618{
2637 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 2619 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2638 int ret; 2620 int ret;
@@ -2917,12 +2899,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2917 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 2899 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2918 WIPHY_FLAG_TDLS_EXTERNAL_SETUP; 2900 WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
2919 2901
2920 wiphy->regulatory_flags |=
2921 REGULATORY_CUSTOM_REG |
2922 REGULATORY_STRICT_REG;
2923
2924 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2925
2926#ifdef CONFIG_PM 2902#ifdef CONFIG_PM
2927 wiphy->wowlan = &mwifiex_wowlan_support; 2903 wiphy->wowlan = &mwifiex_wowlan_support;
2928#endif 2904#endif
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
index c5848934f111..908367857d58 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: CFG80211 2 * Marvell Wireless LAN device driver: CFG80211
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 0ddec3d4b059..b8242eb2be6f 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: Channel, Frequence and Power 2 * Marvell Wireless LAN device driver: Channel, Frequence and Power
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index c161141f6c39..baf0aab63c04 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: commands and events 2 * Marvell Wireless LAN device driver: commands and events
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -137,7 +137,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
137 struct host_cmd_ds_command *host_cmd; 137 struct host_cmd_ds_command *host_cmd;
138 uint16_t cmd_code; 138 uint16_t cmd_code;
139 uint16_t cmd_size; 139 uint16_t cmd_size;
140 struct timeval tstamp;
141 unsigned long flags; 140 unsigned long flags;
142 __le32 tmp; 141 __le32 tmp;
143 142
@@ -198,10 +197,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
198 */ 197 */
199 skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len); 198 skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);
200 199
201 do_gettimeofday(&tstamp); 200 dev_dbg(adapter->dev,
202 dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," 201 "cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n", cmd_code,
203 " seqno %#x\n",
204 tstamp.tv_sec, tstamp.tv_usec, cmd_code,
205 le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, 202 le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
206 le16_to_cpu(host_cmd->seq_num)); 203 le16_to_cpu(host_cmd->seq_num));
207 204
@@ -283,6 +280,13 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
283 (adapter->seq_num, priv->bss_num, 280 (adapter->seq_num, priv->bss_num,
284 priv->bss_type))); 281 priv->bss_type)));
285 282
283 dev_dbg(adapter->dev,
284 "cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n",
285 le16_to_cpu(sleep_cfm_buf->command),
286 le16_to_cpu(sleep_cfm_buf->action),
287 le16_to_cpu(sleep_cfm_buf->size),
288 le16_to_cpu(sleep_cfm_buf->seq_num));
289
286 if (adapter->iface_type == MWIFIEX_USB) { 290 if (adapter->iface_type == MWIFIEX_USB) {
287 sleep_cfm_tmp = 291 sleep_cfm_tmp =
288 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) 292 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
@@ -433,7 +437,6 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
433 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 437 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
434 struct sk_buff *skb = adapter->event_skb; 438 struct sk_buff *skb = adapter->event_skb;
435 u32 eventcause = adapter->event_cause; 439 u32 eventcause = adapter->event_cause;
436 struct timeval tstamp;
437 struct mwifiex_rxinfo *rx_info; 440 struct mwifiex_rxinfo *rx_info;
438 441
439 /* Save the last event to debug log */ 442 /* Save the last event to debug log */
@@ -458,11 +461,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
458 rx_info->bss_type = priv->bss_type; 461 rx_info->bss_type = priv->bss_type;
459 } 462 }
460 463
461 if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { 464 dev_dbg(adapter->dev, "EVENT: cause: %#x\n", eventcause);
462 do_gettimeofday(&tstamp); 465 if (eventcause == EVENT_PS_SLEEP || eventcause == EVENT_PS_AWAKE) {
463 dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
464 tstamp.tv_sec, tstamp.tv_usec, eventcause);
465 } else {
466 /* Handle PS_SLEEP/AWAKE events on STA */ 466 /* Handle PS_SLEEP/AWAKE events on STA */
467 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); 467 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
468 if (!priv) 468 if (!priv)
@@ -773,7 +773,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
773 uint16_t orig_cmdresp_no; 773 uint16_t orig_cmdresp_no;
774 uint16_t cmdresp_no; 774 uint16_t cmdresp_no;
775 uint16_t cmdresp_result; 775 uint16_t cmdresp_result;
776 struct timeval tstamp;
777 unsigned long flags; 776 unsigned long flags;
778 777
779 /* Now we got response from FW, cancel the command timer */ 778 /* Now we got response from FW, cancel the command timer */
@@ -831,11 +830,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
831 adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = 830 adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
832 orig_cmdresp_no; 831 orig_cmdresp_no;
833 832
834 do_gettimeofday(&tstamp); 833 dev_dbg(adapter->dev,
835 dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," 834 "cmd: CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x\n",
836 " len %d, seqno 0x%x\n", 835 orig_cmdresp_no, cmdresp_result,
837 tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result, 836 le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
838 le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
839 837
840 if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { 838 if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
841 dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); 839 dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
@@ -895,7 +893,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
895 struct mwifiex_adapter *adapter = 893 struct mwifiex_adapter *adapter =
896 (struct mwifiex_adapter *) function_context; 894 (struct mwifiex_adapter *) function_context;
897 struct cmd_ctrl_node *cmd_node; 895 struct cmd_ctrl_node *cmd_node;
898 struct timeval tstamp;
899 896
900 adapter->is_cmd_timedout = 1; 897 adapter->is_cmd_timedout = 1;
901 if (!adapter->curr_cmd) { 898 if (!adapter->curr_cmd) {
@@ -908,10 +905,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
908 adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; 905 adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
909 adapter->dbg.timeout_cmd_act = 906 adapter->dbg.timeout_cmd_act =
910 adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; 907 adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
911 do_gettimeofday(&tstamp);
912 dev_err(adapter->dev, 908 dev_err(adapter->dev,
913 "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n", 909 "%s: Timeout cmd id = %#x, act = %#x\n", __func__,
914 __func__, tstamp.tv_sec, tstamp.tv_usec,
915 adapter->dbg.timeout_cmd_id, 910 adapter->dbg.timeout_cmd_id,
916 adapter->dbg.timeout_cmd_act); 911 adapter->dbg.timeout_cmd_act);
917 912
@@ -961,6 +956,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
961 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 956 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
962 mwifiex_init_fw_complete(adapter); 957 mwifiex_init_fw_complete(adapter);
963 958
959 if (adapter->if_ops.fw_dump)
960 adapter->if_ops.fw_dump(adapter);
961
964 if (adapter->if_ops.card_reset) 962 if (adapter->if_ops.card_reset)
965 adapter->if_ops.card_reset(adapter); 963 adapter->if_ops.card_reset(adapter);
966} 964}
@@ -1232,6 +1230,10 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
1232 return; 1230 return;
1233 } 1231 }
1234 1232
1233 dev_dbg(adapter->dev,
1234 "cmd: CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x\n",
1235 command, result, le16_to_cpu(cmd->size), seq_num);
1236
1235 /* Get BSS number and corresponding priv */ 1237 /* Get BSS number and corresponding priv */
1236 priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num), 1238 priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
1237 HostCmd_GET_BSS_TYPE(seq_num)); 1239 HostCmd_GET_BSS_TYPE(seq_num));
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 7b419bbcd544..2713f7acd35e 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: debugfs 2 * Marvell Wireless LAN device driver: debugfs
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -692,6 +692,97 @@ done:
692 return ret; 692 return ret;
693} 693}
694 694
695/* Proc hscfg file write handler
696 * This function can be used to configure the host sleep parameters.
697 */
698static ssize_t
699mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
700 size_t count, loff_t *ppos)
701{
702 struct mwifiex_private *priv = (void *)file->private_data;
703 unsigned long addr = get_zeroed_page(GFP_KERNEL);
704 char *buf = (char *)addr;
705 size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
706 int ret, arg_num;
707 struct mwifiex_ds_hs_cfg hscfg;
708 int conditions = HS_CFG_COND_DEF;
709 u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
710
711 if (!buf)
712 return -ENOMEM;
713
714 if (copy_from_user(buf, ubuf, buf_size)) {
715 ret = -EFAULT;
716 goto done;
717 }
718
719 arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
720
721 memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
722
723 if (arg_num > 3) {
724 dev_err(priv->adapter->dev, "Too many arguments\n");
725 ret = -EINVAL;
726 goto done;
727 }
728
729 if (arg_num >= 1 && arg_num < 3)
730 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
731 MWIFIEX_SYNC_CMD, &hscfg);
732
733 if (arg_num) {
734 if (conditions == HS_CFG_CANCEL) {
735 mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
736 ret = count;
737 goto done;
738 }
739 hscfg.conditions = conditions;
740 }
741 if (arg_num >= 2)
742 hscfg.gpio = gpio;
743 if (arg_num == 3)
744 hscfg.gap = gap;
745
746 hscfg.is_invoke_hostcmd = false;
747 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
748 MWIFIEX_SYNC_CMD, &hscfg);
749
750 mwifiex_enable_hs(priv->adapter);
751 priv->adapter->hs_enabling = false;
752 ret = count;
753done:
754 free_page(addr);
755 return ret;
756}
757
758/* Proc hscfg file read handler
759 * This function can be used to read host sleep configuration
760 * parameters from driver.
761 */
762static ssize_t
763mwifiex_hscfg_read(struct file *file, char __user *ubuf,
764 size_t count, loff_t *ppos)
765{
766 struct mwifiex_private *priv = (void *)file->private_data;
767 unsigned long addr = get_zeroed_page(GFP_KERNEL);
768 char *buf = (char *)addr;
769 int pos, ret;
770 struct mwifiex_ds_hs_cfg hscfg;
771
772 if (!buf)
773 return -ENOMEM;
774
775 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
776 MWIFIEX_SYNC_CMD, &hscfg);
777
778 pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
779 hscfg.gpio, hscfg.gap);
780
781 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
782
783 free_page(addr);
784 return ret;
785}
695 786
696#define MWIFIEX_DFS_ADD_FILE(name) do { \ 787#define MWIFIEX_DFS_ADD_FILE(name) do { \
697 if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \ 788 if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
@@ -725,6 +816,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog);
725MWIFIEX_DFS_FILE_READ_OPS(fw_dump); 816MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
726MWIFIEX_DFS_FILE_OPS(regrdwr); 817MWIFIEX_DFS_FILE_OPS(regrdwr);
727MWIFIEX_DFS_FILE_OPS(rdeeprom); 818MWIFIEX_DFS_FILE_OPS(rdeeprom);
819MWIFIEX_DFS_FILE_OPS(hscfg);
728 820
729/* 821/*
730 * This function creates the debug FS directory structure and the files. 822 * This function creates the debug FS directory structure and the files.
@@ -747,6 +839,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
747 MWIFIEX_DFS_ADD_FILE(regrdwr); 839 MWIFIEX_DFS_ADD_FILE(regrdwr);
748 MWIFIEX_DFS_ADD_FILE(rdeeprom); 840 MWIFIEX_DFS_ADD_FILE(rdeeprom);
749 MWIFIEX_DFS_ADD_FILE(fw_dump); 841 MWIFIEX_DFS_ADD_FILE(fw_dump);
842 MWIFIEX_DFS_ADD_FILE(hscfg);
750} 843}
751 844
752/* 845/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 38da6ff6f416..0e03fe39fc35 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: generic data structures and APIs 2 * Marvell Wireless LAN device driver: generic data structures and APIs
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/ethtool.c b/drivers/net/wireless/mwifiex/ethtool.c
index bfb39908b2c6..04e56b5fc535 100644
--- a/drivers/net/wireless/mwifiex/ethtool.c
+++ b/drivers/net/wireless/mwifiex/ethtool.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: ethtool 2 * Marvell Wireless LAN device driver: ethtool
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -64,7 +64,90 @@ static int mwifiex_ethtool_set_wol(struct net_device *dev,
64 return 0; 64 return 0;
65} 65}
66 66
67static int
68mwifiex_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump)
69{
70 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
71 struct mwifiex_adapter *adapter = priv->adapter;
72 struct memory_type_mapping *entry;
73
74 if (!adapter->if_ops.fw_dump)
75 return -ENOTSUPP;
76
77 dump->flag = adapter->curr_mem_idx;
78 dump->version = 1;
79 if (adapter->curr_mem_idx != MWIFIEX_FW_DUMP_IDX) {
80 entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
81 dump->len = entry->mem_size;
82 } else {
83 dump->len = 0;
84 }
85
86 return 0;
87}
88
89static int
90mwifiex_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,
91 void *buffer)
92{
93 u8 *p = buffer;
94 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
95 struct mwifiex_adapter *adapter = priv->adapter;
96 struct memory_type_mapping *entry;
97
98 if (!adapter->if_ops.fw_dump)
99 return -ENOTSUPP;
100
101 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
102 dev_err(adapter->dev, "firmware dump in progress!!\n");
103 return -EBUSY;
104 }
105
106 entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
107
108 if (!entry->mem_ptr)
109 return -EFAULT;
110
111 memcpy(p, entry->mem_ptr, entry->mem_size);
112
113 entry->mem_size = 0;
114 vfree(entry->mem_ptr);
115 entry->mem_ptr = NULL;
116
117 return 0;
118}
119
120static int mwifiex_set_dump(struct net_device *dev, struct ethtool_dump *val)
121{
122 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
123 struct mwifiex_adapter *adapter = priv->adapter;
124
125 if (!adapter->if_ops.fw_dump)
126 return -ENOTSUPP;
127
128 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
129 dev_err(adapter->dev, "firmware dump in progress!!\n");
130 return -EBUSY;
131 }
132
133 if (val->flag == MWIFIEX_FW_DUMP_IDX) {
134 adapter->curr_mem_idx = val->flag;
135 adapter->if_ops.fw_dump(adapter);
136 return 0;
137 }
138
139 if (val->flag < 0 || val->flag >= adapter->num_mem_types)
140 return -EINVAL;
141
142 adapter->curr_mem_idx = val->flag;
143
144 return 0;
145}
146
67const struct ethtool_ops mwifiex_ethtool_ops = { 147const struct ethtool_ops mwifiex_ethtool_ops = {
68 .get_wol = mwifiex_ethtool_get_wol, 148 .get_wol = mwifiex_ethtool_get_wol,
69 .set_wol = mwifiex_ethtool_set_wol, 149 .set_wol = mwifiex_ethtool_set_wol,
150 .get_dump_flag = mwifiex_get_dump_flag,
151 .get_dump_data = mwifiex_get_dump_data,
152 .set_dump = mwifiex_set_dump,
70}; 153};
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 3175dd04834b..49da2d53d294 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: Firmware specific macros & structures 2 * Marvell Wireless LAN device driver: Firmware specific macros & structures
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -713,7 +713,7 @@ struct mwifiex_ie_types_vendor_param_set {
713 u8 ie[MWIFIEX_MAX_VSIE_LEN]; 713 u8 ie[MWIFIEX_MAX_VSIE_LEN];
714}; 714};
715 715
716#define MWIFIEX_TDLS_IDLE_TIMEOUT 60 716#define MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC 60
717 717
718struct mwifiex_ie_types_tdls_idle_timeout { 718struct mwifiex_ie_types_tdls_idle_timeout {
719 struct mwifiex_ie_types_header header; 719 struct mwifiex_ie_types_header header;
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index 3bf3d58bbc02..b933794758b7 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -2,7 +2,7 @@
2 * Marvell Wireless LAN device driver: management IE handling- setting and 2 * Marvell Wireless LAN device driver: management IE handling- setting and
3 * deleting IE. 3 * deleting IE.
4 * 4 *
5 * Copyright (C) 2012, Marvell International Ltd. 5 * Copyright (C) 2012-2014, Marvell International Ltd.
6 * 6 *
7 * This software file (the "File") is distributed by Marvell International 7 * This software file (the "File") is distributed by Marvell International
8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 4ecd0b208ac6..269a277d0a2e 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: HW/FW Initialization 2 * Marvell Wireless LAN device driver: HW/FW Initialization
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -382,6 +382,8 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
382static void 382static void
383mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) 383mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
384{ 384{
385 int idx;
386
385 if (!adapter) { 387 if (!adapter) {
386 pr_err("%s: adapter is NULL\n", __func__); 388 pr_err("%s: adapter is NULL\n", __func__);
387 return; 389 return;
@@ -396,7 +398,16 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
396 dev_dbg(adapter->dev, "info: free cmd buffer\n"); 398 dev_dbg(adapter->dev, "info: free cmd buffer\n");
397 mwifiex_free_cmd_buffer(adapter); 399 mwifiex_free_cmd_buffer(adapter);
398 400
399 dev_dbg(adapter->dev, "info: free scan table\n"); 401 for (idx = 0; idx < adapter->num_mem_types; idx++) {
402 struct memory_type_mapping *entry =
403 &adapter->mem_type_mapping_tbl[idx];
404
405 if (entry->mem_ptr) {
406 vfree(entry->mem_ptr);
407 entry->mem_ptr = NULL;
408 }
409 entry->mem_size = 0;
410 }
400 411
401 if (adapter->sleep_cfm) 412 if (adapter->sleep_cfm)
402 dev_kfree_skb_any(adapter->sleep_cfm); 413 dev_kfree_skb_any(adapter->sleep_cfm);
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 1b576722671d..0847f3e07ab7 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: ioctl data structures & APIs 2 * Marvell Wireless LAN device driver: ioctl data structures & APIs
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 89dc62a467f4..8d6c25908b6d 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: association and ad-hoc start/join 2 * Marvell Wireless LAN device driver: association and ad-hoc start/join
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -949,7 +949,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
949 chan_tlv->chan_scan_param[0].radio_type |= 949 chan_tlv->chan_scan_param[0].radio_type |=
950 (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4); 950 (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
951 else if (adapter->sec_chan_offset == 951 else if (adapter->sec_chan_offset ==
952 IEEE80211_HT_PARAM_CHA_SEC_ABOVE) 952 IEEE80211_HT_PARAM_CHA_SEC_BELOW)
953 chan_tlv->chan_scan_param[0].radio_type |= 953 chan_tlv->chan_scan_param[0].radio_type |=
954 (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); 954 (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
955 } 955 }
@@ -1288,8 +1288,6 @@ done:
1288int mwifiex_associate(struct mwifiex_private *priv, 1288int mwifiex_associate(struct mwifiex_private *priv,
1289 struct mwifiex_bssdescriptor *bss_desc) 1289 struct mwifiex_bssdescriptor *bss_desc)
1290{ 1290{
1291 u8 current_bssid[ETH_ALEN];
1292
1293 /* Return error if the adapter is not STA role or table entry 1291 /* Return error if the adapter is not STA role or table entry
1294 * is not marked as infra. 1292 * is not marked as infra.
1295 */ 1293 */
@@ -1304,10 +1302,6 @@ int mwifiex_associate(struct mwifiex_private *priv,
1304 else 1302 else
1305 mwifiex_set_ba_params(priv); 1303 mwifiex_set_ba_params(priv);
1306 1304
1307 memcpy(&current_bssid,
1308 &priv->curr_bss_params.bss_descriptor.mac_address,
1309 sizeof(current_bssid));
1310
1311 /* Clear any past association response stored for application 1305 /* Clear any past association response stored for application
1312 retrieval */ 1306 retrieval */
1313 priv->assoc_rsp_size = 0; 1307 priv->assoc_rsp_size = 0;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index e91cd0fa5ca8..dfa37eadc4db 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: major functions 2 * Marvell Wireless LAN device driver: major functions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -33,6 +33,7 @@ static void scan_delay_timer_fn(unsigned long data)
33 struct mwifiex_private *priv = (struct mwifiex_private *)data; 33 struct mwifiex_private *priv = (struct mwifiex_private *)data;
34 struct mwifiex_adapter *adapter = priv->adapter; 34 struct mwifiex_adapter *adapter = priv->adapter;
35 struct cmd_ctrl_node *cmd_node, *tmp_node; 35 struct cmd_ctrl_node *cmd_node, *tmp_node;
36 spinlock_t *scan_q_lock = &adapter->scan_pending_q_lock;
36 unsigned long flags; 37 unsigned long flags;
37 38
38 if (adapter->surprise_removed) 39 if (adapter->surprise_removed)
@@ -44,13 +45,13 @@ static void scan_delay_timer_fn(unsigned long data)
44 * Abort scan operation by cancelling all pending scan 45 * Abort scan operation by cancelling all pending scan
45 * commands 46 * commands
46 */ 47 */
47 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 48 spin_lock_irqsave(scan_q_lock, flags);
48 list_for_each_entry_safe(cmd_node, tmp_node, 49 list_for_each_entry_safe(cmd_node, tmp_node,
49 &adapter->scan_pending_q, list) { 50 &adapter->scan_pending_q, list) {
50 list_del(&cmd_node->list); 51 list_del(&cmd_node->list);
51 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 52 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
52 } 53 }
53 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 54 spin_unlock_irqrestore(scan_q_lock, flags);
54 55
55 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 56 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
56 adapter->scan_processing = false; 57 adapter->scan_processing = false;
@@ -79,12 +80,17 @@ static void scan_delay_timer_fn(unsigned long data)
79 */ 80 */
80 adapter->scan_delay_cnt = 0; 81 adapter->scan_delay_cnt = 0;
81 adapter->empty_tx_q_cnt = 0; 82 adapter->empty_tx_q_cnt = 0;
82 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 83 spin_lock_irqsave(scan_q_lock, flags);
84
85 if (list_empty(&adapter->scan_pending_q)) {
86 spin_unlock_irqrestore(scan_q_lock, flags);
87 goto done;
88 }
89
83 cmd_node = list_first_entry(&adapter->scan_pending_q, 90 cmd_node = list_first_entry(&adapter->scan_pending_q,
84 struct cmd_ctrl_node, list); 91 struct cmd_ctrl_node, list);
85 list_del(&cmd_node->list); 92 list_del(&cmd_node->list);
86 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 93 spin_unlock_irqrestore(scan_q_lock, flags);
87 flags);
88 94
89 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, 95 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
90 true); 96 true);
@@ -609,7 +615,6 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
609 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 615 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
610 struct sk_buff *new_skb; 616 struct sk_buff *new_skb;
611 struct mwifiex_txinfo *tx_info; 617 struct mwifiex_txinfo *tx_info;
612 struct timeval tv;
613 618
614 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", 619 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
615 jiffies, priv->bss_type, priv->bss_num); 620 jiffies, priv->bss_type, priv->bss_num);
@@ -657,8 +662,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
657 * firmware for aggregate delay calculation for stats and 662 * firmware for aggregate delay calculation for stats and
658 * MSDU lifetime expiry. 663 * MSDU lifetime expiry.
659 */ 664 */
660 do_gettimeofday(&tv); 665 __net_timestamp(skb);
661 skb->tstamp = timeval_to_ktime(tv);
662 666
663 mwifiex_queue_tx_pkt(priv, skb); 667 mwifiex_queue_tx_pkt(priv, skb);
664 668
@@ -882,6 +886,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
882 goto err_kmalloc; 886 goto err_kmalloc;
883 887
884 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); 888 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
889 if (adapter->if_ops.iface_work)
890 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
885 891
886 /* Register the device. Fill up the private data structure with relevant 892 /* Register the device. Fill up the private data structure with relevant
887 information from the card. */ 893 information from the card. */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1398afa84064..a2733b1e63f9 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: major data structures and prototypes 2 * Marvell Wireless LAN device driver: major data structures and prototypes
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -30,6 +30,7 @@
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <net/sock.h> 31#include <net/sock.h>
32#include <net/lib80211.h> 32#include <net/lib80211.h>
33#include <linux/vmalloc.h>
33#include <linux/firmware.h> 34#include <linux/firmware.h>
34#include <linux/ctype.h> 35#include <linux/ctype.h>
35#include <linux/of.h> 36#include <linux/of.h>
@@ -410,6 +411,29 @@ struct mwifiex_roc_cfg {
410 struct ieee80211_channel chan; 411 struct ieee80211_channel chan;
411}; 412};
412 413
414#define MWIFIEX_FW_DUMP_IDX 0xff
415#define FW_DUMP_MAX_NAME_LEN 8
416#define FW_DUMP_HOST_READY 0xEE
417#define FW_DUMP_DONE 0xFF
418
419struct memory_type_mapping {
420 u8 mem_name[FW_DUMP_MAX_NAME_LEN];
421 u8 *mem_ptr;
422 u32 mem_size;
423 u8 done_flag;
424};
425
426enum rdwr_status {
427 RDWR_STATUS_SUCCESS = 0,
428 RDWR_STATUS_FAILURE = 1,
429 RDWR_STATUS_DONE = 2
430};
431
432enum mwifiex_iface_work_flags {
433 MWIFIEX_IFACE_WORK_FW_DUMP,
434 MWIFIEX_IFACE_WORK_CARD_RESET,
435};
436
413struct mwifiex_adapter; 437struct mwifiex_adapter;
414struct mwifiex_private; 438struct mwifiex_private;
415 439
@@ -674,6 +698,7 @@ struct mwifiex_if_ops {
674 void (*card_reset) (struct mwifiex_adapter *); 698 void (*card_reset) (struct mwifiex_adapter *);
675 void (*fw_dump)(struct mwifiex_adapter *); 699 void (*fw_dump)(struct mwifiex_adapter *);
676 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 700 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
701 void (*iface_work)(struct work_struct *work);
677}; 702};
678 703
679struct mwifiex_adapter { 704struct mwifiex_adapter {
@@ -809,6 +834,11 @@ struct mwifiex_adapter {
809 bool ext_scan; 834 bool ext_scan;
810 u8 fw_api_ver; 835 u8 fw_api_ver;
811 u8 fw_key_api_major_ver, fw_key_api_minor_ver; 836 u8 fw_key_api_major_ver, fw_key_api_minor_ver;
837 struct work_struct iface_work;
838 unsigned long iface_work_flags;
839 struct memory_type_mapping *mem_type_mapping_tbl;
840 u8 num_mem_types;
841 u8 curr_mem_idx;
812}; 842};
813 843
814int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 844int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -890,6 +920,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
890void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); 920void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
891void mwifiex_hs_activated_event(struct mwifiex_private *priv, 921void mwifiex_hs_activated_event(struct mwifiex_private *priv,
892 u8 activated); 922 u8 activated);
923int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
924 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg);
893int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, 925int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
894 struct host_cmd_ds_command *resp); 926 struct host_cmd_ds_command *resp);
895int mwifiex_process_rx_packet(struct mwifiex_private *priv, 927int mwifiex_process_rx_packet(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 2cc9b6fca490..ff0545888dd0 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: PCIE specific handling 2 * Marvell Wireless LAN device driver: PCIE specific handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -37,6 +37,13 @@ static struct mwifiex_if_ops pcie_ops;
37 37
38static struct semaphore add_remove_card_sem; 38static struct semaphore add_remove_card_sem;
39 39
40static 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},
45};
46
40static int 47static int
41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, 48mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
42 size_t size, int flags) 49 size_t size, int flags)
@@ -192,6 +199,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
192 card->pcie.reg = data->reg; 199 card->pcie.reg = data->reg;
193 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 200 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
194 card->pcie.tx_buf_size = data->tx_buf_size; 201 card->pcie.tx_buf_size = data->tx_buf_size;
202 card->pcie.supports_fw_dump = data->supports_fw_dump;
195 } 203 }
196 204
197 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, 205 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -221,6 +229,8 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
221 if (!adapter || !adapter->priv_num) 229 if (!adapter || !adapter->priv_num)
222 return; 230 return;
223 231
232 cancel_work_sync(&adapter->iface_work);
233
224 if (user_rmmod) { 234 if (user_rmmod) {
225#ifdef CONFIG_PM_SLEEP 235#ifdef CONFIG_PM_SLEEP
226 if (adapter->is_suspended) 236 if (adapter->is_suspended)
@@ -247,7 +257,7 @@ static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
247 return; 257 return;
248} 258}
249 259
250static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { 260static const struct pci_device_id mwifiex_ids[] = {
251 { 261 {
252 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, 262 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
253 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 263 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -307,6 +317,17 @@ static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
307 return 0; 317 return 0;
308} 318}
309 319
320/* This function reads u8 data from PCIE card register. */
321static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
322 int reg, u8 *data)
323{
324 struct pcie_service_card *card = adapter->card;
325
326 *data = ioread8(card->pci_mmap1 + reg);
327
328 return 0;
329}
330
310/* 331/*
311 * This function adds delay loop to ensure FW is awake before proceeding. 332 * This function adds delay loop to ensure FW is awake before proceeding.
312 */ 333 */
@@ -2173,6 +2194,168 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2173 return 0; 2194 return 0;
2174} 2195}
2175 2196
2197/* This function read/write firmware */
2198static enum rdwr_status
2199mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2200{
2201 int ret, tries;
2202 u8 ctrl_data;
2203 struct pcie_service_card *card = adapter->card;
2204 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2205
2206 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
2207 if (ret) {
2208 dev_err(adapter->dev, "PCIE write err\n");
2209 return RDWR_STATUS_FAILURE;
2210 }
2211
2212 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2213 mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
2214 if (ctrl_data == FW_DUMP_DONE)
2215 return RDWR_STATUS_SUCCESS;
2216 if (doneflag && ctrl_data == doneflag)
2217 return RDWR_STATUS_DONE;
2218 if (ctrl_data != FW_DUMP_HOST_READY) {
2219 dev_info(adapter->dev,
2220 "The ctrl reg was changed, re-try again!\n");
2221 mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2222 FW_DUMP_HOST_READY);
2223 if (ret) {
2224 dev_err(adapter->dev, "PCIE write err\n");
2225 return RDWR_STATUS_FAILURE;
2226 }
2227 }
2228 usleep_range(100, 200);
2229 }
2230
2231 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2232 return RDWR_STATUS_FAILURE;
2233}
2234
2235/* This function dump firmware memory to file */
2236static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2237{
2238 struct pcie_service_card *card = adapter->card;
2239 const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
2240 unsigned int reg, reg_start, reg_end;
2241 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2242 enum rdwr_status stat;
2243 u32 memory_size;
2244 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2245
2246 if (!card->pcie.supports_fw_dump)
2247 return;
2248
2249 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2250 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2251
2252 if (entry->mem_ptr) {
2253 vfree(entry->mem_ptr);
2254 entry->mem_ptr = NULL;
2255 }
2256 entry->mem_size = 0;
2257 }
2258
2259 dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
2260
2261 /* Read the number of the memories which will dump */
2262 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2263 if (stat == RDWR_STATUS_FAILURE)
2264 goto done;
2265
2266 reg = creg->fw_dump_start;
2267 mwifiex_read_reg_byte(adapter, reg, &dump_num);
2268
2269 /* Read the length of every memory which will dump */
2270 for (idx = 0; idx < dump_num; idx++) {
2271 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2272
2273 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2274 if (stat == RDWR_STATUS_FAILURE)
2275 goto done;
2276
2277 memory_size = 0;
2278 reg = creg->fw_dump_start;
2279 for (i = 0; i < 4; i++) {
2280 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2281 memory_size |= (read_reg << (i * 8));
2282 reg++;
2283 }
2284
2285 if (memory_size == 0) {
2286 dev_info(adapter->dev, "Firmware dump Finished!\n");
2287 break;
2288 }
2289
2290 dev_info(adapter->dev,
2291 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2292 entry->mem_ptr = vmalloc(memory_size + 1);
2293 entry->mem_size = memory_size;
2294 if (!entry->mem_ptr) {
2295 dev_err(adapter->dev,
2296 "Vmalloc %s failed\n", entry->mem_name);
2297 goto done;
2298 }
2299 dbg_ptr = entry->mem_ptr;
2300 end_ptr = dbg_ptr + memory_size;
2301
2302 doneflag = entry->done_flag;
2303 dev_info(adapter->dev, "Start %s output, please wait...\n",
2304 entry->mem_name);
2305
2306 do {
2307 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2308 if (RDWR_STATUS_FAILURE == stat)
2309 goto done;
2310
2311 reg_start = creg->fw_dump_start;
2312 reg_end = creg->fw_dump_end;
2313 for (reg = reg_start; reg <= reg_end; reg++) {
2314 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
2315 if (dbg_ptr < end_ptr)
2316 dbg_ptr++;
2317 else
2318 dev_err(adapter->dev,
2319 "Allocated buf not enough\n");
2320 }
2321
2322 if (stat != RDWR_STATUS_DONE)
2323 continue;
2324
2325 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2326 entry->mem_name, dbg_ptr - entry->mem_ptr);
2327 break;
2328 } while (true);
2329 }
2330 dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
2331
2332 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2333
2334done:
2335 adapter->curr_mem_idx = 0;
2336}
2337
2338static void mwifiex_pcie_work(struct work_struct *work)
2339{
2340 struct mwifiex_adapter *adapter =
2341 container_of(work, struct mwifiex_adapter, iface_work);
2342
2343 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2344 &adapter->iface_work_flags))
2345 mwifiex_pcie_fw_dump_work(adapter);
2346}
2347
2348/* This function dumps FW information */
2349static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2350{
2351 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
2352 return;
2353
2354 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
2355
2356 schedule_work(&adapter->iface_work);
2357}
2358
2176/* 2359/*
2177 * This function initializes the PCI-E host memory space, WCB rings, etc. 2360 * This function initializes the PCI-E host memory space, WCB rings, etc.
2178 * 2361 *
@@ -2342,6 +2525,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2342 2525
2343 adapter->dev = &pdev->dev; 2526 adapter->dev = &pdev->dev;
2344 adapter->tx_buf_size = card->pcie.tx_buf_size; 2527 adapter->tx_buf_size = card->pcie.tx_buf_size;
2528 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
2529 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
2345 strcpy(adapter->fw_name, card->pcie.firmware); 2530 strcpy(adapter->fw_name, card->pcie.firmware);
2346 2531
2347 return 0; 2532 return 0;
@@ -2394,6 +2579,8 @@ static struct mwifiex_if_ops pcie_ops = {
2394 .cleanup_mpa_buf = NULL, 2579 .cleanup_mpa_buf = NULL,
2395 .init_fw_port = mwifiex_pcie_init_fw_port, 2580 .init_fw_port = mwifiex_pcie_init_fw_port,
2396 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, 2581 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
2582 .fw_dump = mwifiex_pcie_fw_dump,
2583 .iface_work = mwifiex_pcie_work,
2397}; 2584};
2398 2585
2399/* 2586/*
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index e8ec561f8a64..a1a8fd3bc1be 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -3,7 +3,7 @@
3 * @brief This file contains definitions for PCI-E interface. 3 * @brief This file contains definitions for PCI-E interface.
4 * driver. 4 * driver.
5 * 5 *
6 * Copyright (C) 2011, Marvell International Ltd. 6 * Copyright (C) 2011-2014, Marvell International Ltd.
7 * 7 *
8 * This software file (the "File") is distributed by Marvell International 8 * This software file (the "File") is distributed by Marvell International
9 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 9 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -129,6 +129,9 @@ struct mwifiex_pcie_card_reg {
129 u32 ring_tx_start_ptr; 129 u32 ring_tx_start_ptr;
130 u8 pfu_enabled; 130 u8 pfu_enabled;
131 u8 sleep_cookie; 131 u8 sleep_cookie;
132 u16 fw_dump_ctrl;
133 u16 fw_dump_start;
134 u16 fw_dump_end;
132}; 135};
133 136
134static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { 137static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = {
@@ -191,6 +194,9 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = {
191 .ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR, 194 .ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
192 .pfu_enabled = 1, 195 .pfu_enabled = 1,
193 .sleep_cookie = 0, 196 .sleep_cookie = 0,
197 .fw_dump_ctrl = 0xcf4,
198 .fw_dump_start = 0xcf8,
199 .fw_dump_end = 0xcff
194}; 200};
195 201
196struct mwifiex_pcie_device { 202struct mwifiex_pcie_device {
@@ -198,6 +204,7 @@ struct mwifiex_pcie_device {
198 const struct mwifiex_pcie_card_reg *reg; 204 const struct mwifiex_pcie_card_reg *reg;
199 u16 blksz_fw_dl; 205 u16 blksz_fw_dl;
200 u16 tx_buf_size; 206 u16 tx_buf_size;
207 bool supports_fw_dump;
201}; 208};
202 209
203static const struct mwifiex_pcie_device mwifiex_pcie8766 = { 210static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
@@ -205,6 +212,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
205 .reg = &mwifiex_reg_8766, 212 .reg = &mwifiex_reg_8766,
206 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 213 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
207 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 214 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
215 .supports_fw_dump = false,
208}; 216};
209 217
210static const struct mwifiex_pcie_device mwifiex_pcie8897 = { 218static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
@@ -212,6 +220,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
212 .reg = &mwifiex_reg_8897, 220 .reg = &mwifiex_reg_8897,
213 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 221 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
214 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 222 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
223 .supports_fw_dump = true,
215}; 224};
216 225
217struct mwifiex_evt_buf_desc { 226struct mwifiex_evt_buf_desc {
@@ -322,4 +331,5 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
322 331
323 return 0; 332 return 0;
324} 333}
334
325#endif /* _MWIFIEX_PCIE_H */ 335#endif /* _MWIFIEX_PCIE_H */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 45c5b3450cf5..dee717a19ddb 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: scan ioctl and command handling 2 * Marvell Wireless LAN device driver: scan ioctl and command handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 4ce3d7b33991..1770fa3fc1e6 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: SDIO specific handling 2 * Marvell Wireless LAN device driver: SDIO specific handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -50,6 +50,24 @@ static struct mwifiex_if_ops sdio_ops;
50 50
51static struct semaphore add_remove_card_sem; 51static struct semaphore add_remove_card_sem;
52 52
53static struct memory_type_mapping mem_type_mapping_tbl[] = {
54 {"ITCM", NULL, 0, 0xF0},
55 {"DTCM", NULL, 0, 0xF1},
56 {"SQRAM", NULL, 0, 0xF2},
57 {"APU", NULL, 0, 0xF3},
58 {"CIU", NULL, 0, 0xF4},
59 {"ICU", NULL, 0, 0xF5},
60 {"MAC", NULL, 0, 0xF6},
61 {"EXT7", NULL, 0, 0xF7},
62 {"EXT8", NULL, 0, 0xF8},
63 {"EXT9", NULL, 0, 0xF9},
64 {"EXT10", NULL, 0, 0xFA},
65 {"EXT11", NULL, 0, 0xFB},
66 {"EXT12", NULL, 0, 0xFC},
67 {"EXT13", NULL, 0, 0xFD},
68 {"EXTLAST", NULL, 0, 0xFE},
69};
70
53/* 71/*
54 * SDIO probe. 72 * SDIO probe.
55 * 73 *
@@ -87,6 +105,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
87 card->tx_buf_size = data->tx_buf_size; 105 card->tx_buf_size = data->tx_buf_size;
88 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size; 106 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;
89 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size; 107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;
108 card->supports_fw_dump = data->supports_fw_dump;
90 } 109 }
91 110
92 sdio_claim_host(func); 111 sdio_claim_host(func);
@@ -179,6 +198,8 @@ mwifiex_sdio_remove(struct sdio_func *func)
179 if (!adapter || !adapter->priv_num) 198 if (!adapter || !adapter->priv_num)
180 return; 199 return;
181 200
201 cancel_work_sync(&adapter->iface_work);
202
182 if (user_rmmod) { 203 if (user_rmmod) {
183 if (adapter->is_suspended) 204 if (adapter->is_suspended)
184 mwifiex_sdio_resume(adapter->dev); 205 mwifiex_sdio_resume(adapter->dev);
@@ -1777,6 +1798,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1777 adapter->dev = &func->dev; 1798 adapter->dev = &func->dev;
1778 1799
1779 strcpy(adapter->fw_name, card->firmware); 1800 strcpy(adapter->fw_name, card->firmware);
1801 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
1802 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
1780 1803
1781 return 0; 1804 return 0;
1782} 1805}
@@ -1914,10 +1937,10 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1914 port, card->mp_data_port_mask); 1937 port, card->mp_data_port_mask);
1915} 1938}
1916 1939
1917static struct mmc_host *reset_host; 1940static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
1918static void sdio_card_reset_worker(struct work_struct *work)
1919{ 1941{
1920 struct mmc_host *target = reset_host; 1942 struct sdio_mmc_card *card = adapter->card;
1943 struct mmc_host *target = card->func->card->host;
1921 1944
1922 /* The actual reset operation must be run outside of driver thread. 1945 /* The actual reset operation must be run outside of driver thread.
1923 * This is because mmc_remove_host() will cause the device to be 1946 * This is because mmc_remove_host() will cause the device to be
@@ -1931,17 +1954,210 @@ static void sdio_card_reset_worker(struct work_struct *work)
1931 mmc_remove_host(target); 1954 mmc_remove_host(target);
1932 /* 20ms delay is based on experiment with sdhci controller */ 1955 /* 20ms delay is based on experiment with sdhci controller */
1933 mdelay(20); 1956 mdelay(20);
1957 target->rescan_entered = 0; /* rescan non-removable cards */
1934 mmc_add_host(target); 1958 mmc_add_host(target);
1935} 1959}
1936static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); 1960
1961/* This function read/write firmware */
1962static enum
1963rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,
1964 u8 doneflag)
1965{
1966 struct sdio_mmc_card *card = adapter->card;
1967 int ret, tries;
1968 u8 ctrl_data = 0;
1969
1970 sdio_writeb(card->func, FW_DUMP_HOST_READY, card->reg->fw_dump_ctrl,
1971 &ret);
1972 if (ret) {
1973 dev_err(adapter->dev, "SDIO Write ERR\n");
1974 return RDWR_STATUS_FAILURE;
1975 }
1976 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
1977 ctrl_data = sdio_readb(card->func, card->reg->fw_dump_ctrl,
1978 &ret);
1979 if (ret) {
1980 dev_err(adapter->dev, "SDIO read err\n");
1981 return RDWR_STATUS_FAILURE;
1982 }
1983 if (ctrl_data == FW_DUMP_DONE)
1984 break;
1985 if (doneflag && ctrl_data == doneflag)
1986 return RDWR_STATUS_DONE;
1987 if (ctrl_data != FW_DUMP_HOST_READY) {
1988 dev_info(adapter->dev,
1989 "The ctrl reg was changed, re-try again!\n");
1990 sdio_writeb(card->func, FW_DUMP_HOST_READY,
1991 card->reg->fw_dump_ctrl, &ret);
1992 if (ret) {
1993 dev_err(adapter->dev, "SDIO write err\n");
1994 return RDWR_STATUS_FAILURE;
1995 }
1996 }
1997 usleep_range(100, 200);
1998 }
1999 if (ctrl_data == FW_DUMP_HOST_READY) {
2000 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2001 return RDWR_STATUS_FAILURE;
2002 }
2003
2004 return RDWR_STATUS_SUCCESS;
2005}
2006
2007/* This function dump firmware memory to file */
2008static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
2009{
2010 struct mwifiex_adapter *adapter =
2011 container_of(work, struct mwifiex_adapter, iface_work);
2012 struct sdio_mmc_card *card = adapter->card;
2013 int ret = 0;
2014 unsigned int reg, reg_start, reg_end;
2015 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2016 enum rdwr_status stat;
2017 u32 memory_size;
2018 static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL };
2019
2020 if (!card->supports_fw_dump)
2021 return;
2022
2023 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2024 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2025
2026 if (entry->mem_ptr) {
2027 vfree(entry->mem_ptr);
2028 entry->mem_ptr = NULL;
2029 }
2030 entry->mem_size = 0;
2031 }
2032
2033 mwifiex_pm_wakeup_card(adapter);
2034 sdio_claim_host(card->func);
2035
2036 dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
2037
2038 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
2039 if (stat == RDWR_STATUS_FAILURE)
2040 goto done;
2041
2042 reg = card->reg->fw_dump_start;
2043 /* Read the number of the memories which will dump */
2044 dump_num = sdio_readb(card->func, reg, &ret);
2045 if (ret) {
2046 dev_err(adapter->dev, "SDIO read memory length err\n");
2047 goto done;
2048 }
2049
2050 /* Read the length of every memory which will dump */
2051 for (idx = 0; idx < dump_num; idx++) {
2052 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2053
2054 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
2055 if (stat == RDWR_STATUS_FAILURE)
2056 goto done;
2057
2058 memory_size = 0;
2059 reg = card->reg->fw_dump_start;
2060 for (i = 0; i < 4; i++) {
2061 read_reg = sdio_readb(card->func, reg, &ret);
2062 if (ret) {
2063 dev_err(adapter->dev, "SDIO read err\n");
2064 goto done;
2065 }
2066 memory_size |= (read_reg << i*8);
2067 reg++;
2068 }
2069
2070 if (memory_size == 0) {
2071 dev_info(adapter->dev, "Firmware dump Finished!\n");
2072 break;
2073 }
2074
2075 dev_info(adapter->dev,
2076 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2077 entry->mem_ptr = vmalloc(memory_size + 1);
2078 entry->mem_size = memory_size;
2079 if (!entry->mem_ptr) {
2080 dev_err(adapter->dev, "Vmalloc %s failed\n",
2081 entry->mem_name);
2082 goto done;
2083 }
2084 dbg_ptr = entry->mem_ptr;
2085 end_ptr = dbg_ptr + memory_size;
2086
2087 doneflag = entry->done_flag;
2088 dev_info(adapter->dev, "Start %s output, please wait...\n",
2089 entry->mem_name);
2090
2091 do {
2092 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
2093 if (stat == RDWR_STATUS_FAILURE)
2094 goto done;
2095
2096 reg_start = card->reg->fw_dump_start;
2097 reg_end = card->reg->fw_dump_end;
2098 for (reg = reg_start; reg <= reg_end; reg++) {
2099 *dbg_ptr = sdio_readb(card->func, reg, &ret);
2100 if (ret) {
2101 dev_err(adapter->dev,
2102 "SDIO read err\n");
2103 goto done;
2104 }
2105 if (dbg_ptr < end_ptr)
2106 dbg_ptr++;
2107 else
2108 dev_err(adapter->dev,
2109 "Allocated buf not enough\n");
2110 }
2111
2112 if (stat != RDWR_STATUS_DONE)
2113 continue;
2114
2115 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2116 entry->mem_name, dbg_ptr - entry->mem_ptr);
2117 break;
2118 } while (1);
2119 }
2120 dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
2121
2122 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2123
2124done:
2125 sdio_release_host(card->func);
2126 adapter->curr_mem_idx = 0;
2127}
2128
2129static void mwifiex_sdio_work(struct work_struct *work)
2130{
2131 struct mwifiex_adapter *adapter =
2132 container_of(work, struct mwifiex_adapter, iface_work);
2133
2134 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2135 &adapter->iface_work_flags))
2136 mwifiex_sdio_card_reset_work(adapter);
2137 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2138 &adapter->iface_work_flags))
2139 mwifiex_sdio_fw_dump_work(work);
2140}
1937 2141
1938/* This function resets the card */ 2142/* This function resets the card */
1939static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) 2143static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
1940{ 2144{
1941 struct sdio_mmc_card *card = adapter->card; 2145 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags))
2146 return;
2147
2148 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags);
2149
2150 schedule_work(&adapter->iface_work);
2151}
2152
2153/* This function dumps FW information */
2154static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2155{
2156 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
2157 return;
1942 2158
1943 reset_host = card->func->card->host; 2159 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
1944 schedule_work(&card_reset_work); 2160 schedule_work(&adapter->iface_work);
1945} 2161}
1946 2162
1947static struct mwifiex_if_ops sdio_ops = { 2163static struct mwifiex_if_ops sdio_ops = {
@@ -1964,6 +2180,8 @@ static struct mwifiex_if_ops sdio_ops = {
1964 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, 2180 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
1965 .event_complete = mwifiex_sdio_event_complete, 2181 .event_complete = mwifiex_sdio_event_complete,
1966 .card_reset = mwifiex_sdio_card_reset, 2182 .card_reset = mwifiex_sdio_card_reset,
2183 .iface_work = mwifiex_sdio_work,
2184 .fw_dump = mwifiex_sdio_fw_dump,
1967}; 2185};
1968 2186
1969/* 2187/*
@@ -2001,7 +2219,6 @@ mwifiex_sdio_cleanup_module(void)
2001 /* Set the flag as user is removing this module. */ 2219 /* Set the flag as user is removing this module. */
2002 user_rmmod = 1; 2220 user_rmmod = 1;
2003 2221
2004 cancel_work_sync(&card_reset_work);
2005 sdio_unregister_driver(&mwifiex_sdio); 2222 sdio_unregister_driver(&mwifiex_sdio);
2006} 2223}
2007 2224
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 6eea30b43ed7..6b8835ec88f1 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: SDIO specific definitions 2 * Marvell Wireless LAN device driver: SDIO specific definitions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -219,6 +219,9 @@ struct mwifiex_sdio_card_reg {
219 u8 rd_len_p0_l; 219 u8 rd_len_p0_l;
220 u8 rd_len_p0_u; 220 u8 rd_len_p0_u;
221 u8 card_misc_cfg_reg; 221 u8 card_misc_cfg_reg;
222 u8 fw_dump_ctrl;
223 u8 fw_dump_start;
224 u8 fw_dump_end;
222}; 225};
223 226
224struct sdio_mmc_card { 227struct sdio_mmc_card {
@@ -231,6 +234,7 @@ struct sdio_mmc_card {
231 u8 mp_agg_pkt_limit; 234 u8 mp_agg_pkt_limit;
232 bool supports_sdio_new_mode; 235 bool supports_sdio_new_mode;
233 bool has_control_mask; 236 bool has_control_mask;
237 bool supports_fw_dump;
234 u16 tx_buf_size; 238 u16 tx_buf_size;
235 u32 mp_tx_agg_buf_size; 239 u32 mp_tx_agg_buf_size;
236 u32 mp_rx_agg_buf_size; 240 u32 mp_rx_agg_buf_size;
@@ -257,6 +261,7 @@ struct mwifiex_sdio_device {
257 u8 mp_agg_pkt_limit; 261 u8 mp_agg_pkt_limit;
258 bool supports_sdio_new_mode; 262 bool supports_sdio_new_mode;
259 bool has_control_mask; 263 bool has_control_mask;
264 bool supports_fw_dump;
260 u16 tx_buf_size; 265 u16 tx_buf_size;
261 u32 mp_tx_agg_buf_size; 266 u32 mp_tx_agg_buf_size;
262 u32 mp_rx_agg_buf_size; 267 u32 mp_rx_agg_buf_size;
@@ -307,6 +312,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
307 .rd_len_p0_l = 0x0c, 312 .rd_len_p0_l = 0x0c,
308 .rd_len_p0_u = 0x0d, 313 .rd_len_p0_u = 0x0d,
309 .card_misc_cfg_reg = 0xcc, 314 .card_misc_cfg_reg = 0xcc,
315 .fw_dump_ctrl = 0xe2,
316 .fw_dump_start = 0xe3,
317 .fw_dump_end = 0xea,
310}; 318};
311 319
312static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { 320static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
@@ -319,6 +327,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
319 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 327 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
320 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 328 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
321 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 329 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
330 .supports_fw_dump = false,
322}; 331};
323 332
324static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { 333static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -331,6 +340,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
331 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 340 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
332 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 341 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
333 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 342 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
343 .supports_fw_dump = false,
334}; 344};
335 345
336static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { 346static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -343,6 +353,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
343 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 353 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
344 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 354 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
345 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 355 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
356 .supports_fw_dump = false,
346}; 357};
347 358
348static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { 359static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -355,6 +366,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
355 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 366 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
356 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 367 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
357 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 368 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
369 .supports_fw_dump = true,
358}; 370};
359 371
360/* 372/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 88202ce0c139..733de92a4c61 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station command handling 2 * Marvell Wireless LAN device driver: station command handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -1647,7 +1647,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1647 timeout = (void *)(pos + config_len); 1647 timeout = (void *)(pos + config_len);
1648 timeout->header.type = cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT); 1648 timeout->header.type = cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT);
1649 timeout->header.len = cpu_to_le16(sizeof(timeout->value)); 1649 timeout->header.len = cpu_to_le16(sizeof(timeout->value));
1650 timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT); 1650 timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC);
1651 config_len += sizeof(struct mwifiex_ie_types_tdls_idle_timeout); 1651 config_len += sizeof(struct mwifiex_ie_types_tdls_idle_timeout);
1652 1652
1653 break; 1653 break;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 577f2979ed8f..08b78baeb846 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station command response handling 2 * Marvell Wireless LAN device driver: station command response handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -908,7 +908,7 @@ static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
908 break; 908 break;
909 default: 909 default:
910 dev_err(priv->adapter->dev, 910 dev_err(priv->adapter->dev,
911 "Unknown TDLS command action respnse %d", action); 911 "Unknown TDLS command action response %d", action);
912 return -1; 912 return -1;
913 } 913 }
914 914
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index f6395ef11a72..f1c240eca0cd 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station event handling 2 * Marvell Wireless LAN device driver: station event handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 536c14aa71f3..caae9738100a 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: functions for station ioctl 2 * Marvell Wireless LAN device driver: functions for station ioctl
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -26,7 +26,7 @@
26#include "11n.h" 26#include "11n.h"
27#include "cfg80211.h" 27#include "cfg80211.h"
28 28
29static int disconnect_on_suspend = 1; 29static int disconnect_on_suspend;
30module_param(disconnect_on_suspend, int, 0644); 30module_param(disconnect_on_suspend, int, 0644);
31 31
32/* 32/*
@@ -283,10 +283,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
283 priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { 283 priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
284 u8 config_bands; 284 u8 config_bands;
285 285
286 ret = mwifiex_deauthenticate(priv, NULL);
287 if (ret)
288 goto done;
289
290 if (!bss_desc) 286 if (!bss_desc)
291 return -1; 287 return -1;
292 288
@@ -345,12 +341,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
345 goto done; 341 goto done;
346 } 342 }
347 343
348 /* Exit Adhoc mode first */
349 dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
350 ret = mwifiex_deauthenticate(priv, NULL);
351 if (ret)
352 goto done;
353
354 priv->adhoc_is_link_sensed = false; 344 priv->adhoc_is_link_sensed = false;
355 345
356 ret = mwifiex_check_network_compatibility(priv, bss_desc); 346 ret = mwifiex_check_network_compatibility(priv, bss_desc);
@@ -389,8 +379,8 @@ done:
389 * This function prepares the correct firmware command and 379 * This function prepares the correct firmware command and
390 * issues it. 380 * issues it.
391 */ 381 */
392static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, 382int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
393 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) 383 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
394 384
395{ 385{
396 struct mwifiex_adapter *adapter = priv->adapter; 386 struct mwifiex_adapter *adapter = priv->adapter;
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 8b639d7fe6df..9ceb1dbe34c5 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station RX data handling 2 * Marvell Wireless LAN device driver: station RX data handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 70eb863c7249..dab7b33c54be 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station TX data handling 2 * Marvell Wireless LAN device driver: station TX data handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 0e88364e0c67..4c5fd953893d 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -530,7 +530,6 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
530{ 530{
531 struct sk_buff *skb; 531 struct sk_buff *skb;
532 struct mwifiex_txinfo *tx_info; 532 struct mwifiex_txinfo *tx_info;
533 struct timeval tv;
534 int ret; 533 int ret;
535 u16 skb_len; 534 u16 skb_len;
536 535
@@ -609,8 +608,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
609 tx_info->bss_num = priv->bss_num; 608 tx_info->bss_num = priv->bss_num;
610 tx_info->bss_type = priv->bss_type; 609 tx_info->bss_type = priv->bss_type;
611 610
612 do_gettimeofday(&tv); 611 __net_timestamp(skb);
613 skb->tstamp = timeval_to_ktime(tv);
614 mwifiex_queue_tx_pkt(priv, skb); 612 mwifiex_queue_tx_pkt(priv, skb);
615 613
616 return 0; 614 return 0;
@@ -703,7 +701,6 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
703{ 701{
704 struct sk_buff *skb; 702 struct sk_buff *skb;
705 struct mwifiex_txinfo *tx_info; 703 struct mwifiex_txinfo *tx_info;
706 struct timeval tv;
707 u8 *pos; 704 u8 *pos;
708 u32 pkt_type, tx_control; 705 u32 pkt_type, tx_control;
709 u16 pkt_len, skb_len; 706 u16 pkt_len, skb_len;
@@ -769,8 +766,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
769 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len); 766 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
770 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len, 767 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
771 sizeof(pkt_len)); 768 sizeof(pkt_len));
772 do_gettimeofday(&tv); 769 __net_timestamp(skb);
773 skb->tstamp = timeval_to_ktime(tv);
774 mwifiex_queue_tx_pkt(priv, skb); 770 mwifiex_queue_tx_pkt(priv, skb);
775 771
776 return 0; 772 return 0;
@@ -785,6 +781,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
785 struct mwifiex_sta_node *sta_ptr; 781 struct mwifiex_sta_node *sta_ptr;
786 u8 *peer, *pos, *end; 782 u8 *peer, *pos, *end;
787 u8 i, action, basic; 783 u8 i, action, basic;
784 __le16 cap = 0;
788 int ie_len = 0; 785 int ie_len = 0;
789 786
790 if (len < (sizeof(struct ethhdr) + 3)) 787 if (len < (sizeof(struct ethhdr) + 3))
@@ -796,18 +793,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
796 793
797 peer = buf + ETH_ALEN; 794 peer = buf + ETH_ALEN;
798 action = *(buf + sizeof(struct ethhdr) + 2); 795 action = *(buf + sizeof(struct ethhdr) + 2);
799
800 /* just handle TDLS setup request/response/confirm */
801 if (action > WLAN_TDLS_SETUP_CONFIRM)
802 return;
803
804 dev_dbg(priv->adapter->dev, 796 dev_dbg(priv->adapter->dev,
805 "rx:tdls action: peer=%pM, action=%d\n", peer, action); 797 "rx:tdls action: peer=%pM, action=%d\n", peer, action);
806 798
807 sta_ptr = mwifiex_add_sta_entry(priv, peer);
808 if (!sta_ptr)
809 return;
810
811 switch (action) { 799 switch (action) {
812 case WLAN_TDLS_SETUP_REQUEST: 800 case WLAN_TDLS_SETUP_REQUEST:
813 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN)) 801 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
@@ -815,7 +803,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
815 803
816 pos = buf + sizeof(struct ethhdr) + 4; 804 pos = buf + sizeof(struct ethhdr) + 4;
817 /* payload 1+ category 1 + action 1 + dialog 1 */ 805 /* payload 1+ category 1 + action 1 + dialog 1 */
818 sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos); 806 cap = cpu_to_le16(*(u16 *)pos);
819 ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; 807 ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
820 pos += 2; 808 pos += 2;
821 break; 809 break;
@@ -825,7 +813,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
825 return; 813 return;
826 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ 814 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
827 pos = buf + sizeof(struct ethhdr) + 6; 815 pos = buf + sizeof(struct ethhdr) + 6;
828 sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos); 816 cap = cpu_to_le16(*(u16 *)pos);
829 ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; 817 ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
830 pos += 2; 818 pos += 2;
831 break; 819 break;
@@ -837,10 +825,16 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
837 ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; 825 ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
838 break; 826 break;
839 default: 827 default:
840 dev_warn(priv->adapter->dev, "Unknown TDLS frame type.\n"); 828 dev_dbg(priv->adapter->dev, "Unknown TDLS frame type.\n");
841 return; 829 return;
842 } 830 }
843 831
832 sta_ptr = mwifiex_add_sta_entry(priv, peer);
833 if (!sta_ptr)
834 return;
835
836 sta_ptr->tdls_cap.capab = cap;
837
844 for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) { 838 for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
845 if (pos + 2 + pos[1] > end) 839 if (pos + 2 + pos[1] > end)
846 break; 840 break;
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index fd7e5b9b4581..96a2126cc44b 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: generic TX/RX data handling 2 * Marvell Wireless LAN device driver: generic TX/RX data handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 32643555dd2a..300bab438011 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: AP specific command handling 2 * Marvell Wireless LAN device driver: AP specific command handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 92e77a398ecf..7c2b97660a03 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: AP event handling 2 * Marvell Wireless LAN device driver: AP event handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index b0601b91cc4f..ec7309d096ab 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: AP TX and RX data handling 2 * Marvell Wireless LAN device driver: AP TX and RX data handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -96,7 +96,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
96 struct sk_buff *new_skb; 96 struct sk_buff *new_skb;
97 struct mwifiex_txinfo *tx_info; 97 struct mwifiex_txinfo *tx_info;
98 int hdr_chop; 98 int hdr_chop;
99 struct timeval tv;
100 struct ethhdr *p_ethhdr; 99 struct ethhdr *p_ethhdr;
101 100
102 uap_rx_pd = (struct uap_rxpd *)(skb->data); 101 uap_rx_pd = (struct uap_rxpd *)(skb->data);
@@ -193,8 +192,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
193 tx_info->pkt_len = skb->len; 192 tx_info->pkt_len = skb->len;
194 } 193 }
195 194
196 do_gettimeofday(&tv); 195 __net_timestamp(skb);
197 skb->tstamp = timeval_to_ktime(tv);
198 mwifiex_wmm_add_buf_txqueue(priv, skb); 196 mwifiex_wmm_add_buf_txqueue(priv, skb);
199 atomic_inc(&adapter->tx_pending); 197 atomic_inc(&adapter->tx_pending);
200 atomic_inc(&adapter->pending_bridged_pkts); 198 atomic_inc(&adapter->pending_bridged_pkts);
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index a8ce8130cfae..7118a18b91ba 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: USB specific handling 2 * Marvell Wireless LAN device driver: USB specific handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index 15b73d12e998..4c41c2a193c5 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file contains definitions for mwifiex USB interface driver. 2 * This file contains definitions for mwifiex USB interface driver.
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 6da5abf52e61..cee028321a9a 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: utility functions 2 * Marvell Wireless LAN device driver: utility functions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index caadb3737b9e..40296cb4a3f1 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: utility functions 2 * Marvell Wireless LAN device driver: utility functions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index d3671d009f6c..94c98a86ebbe 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: WMM 2 * Marvell Wireless LAN device driver: WMM
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -878,15 +878,8 @@ u8
878mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, 878mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
879 const struct sk_buff *skb) 879 const struct sk_buff *skb)
880{ 880{
881 u32 queue_delay = ktime_to_ms(net_timedelta(skb->tstamp));
881 u8 ret_val; 882 u8 ret_val;
882 struct timeval out_tstamp, in_tstamp;
883 u32 queue_delay;
884
885 do_gettimeofday(&out_tstamp);
886 in_tstamp = ktime_to_timeval(skb->tstamp);
887
888 queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000;
889 queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000;
890 883
891 /* 884 /*
892 * Queue delay is passed as a uint8 in units of 2ms (ms shifted 885 * Queue delay is passed as a uint8 in units of 2ms (ms shifted
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index eca56e371a57..569bd73f33c5 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: WMM 2 * Marvell Wireless LAN device driver: WMM
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 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 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991