aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-01 14:27:28 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-01 14:27:28 -0400
commit45eb5168873c93b4f1c3c3867fea65aad4c6abd6 (patch)
tree4949e1083f214ce51565d41614df912cba017219 /drivers/net/wireless/mwifiex
parentb9600d2d0901cd0f91cb372e72bd53d22f49638d (diff)
parent9374e7d2fdcad3c36dafc8d3effd554bc702c4b6 (diff)
Merge tag 'wireless-drivers-next-for-davem-2015-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== Major changes: ath9k: * add Active Interference Cancellation, a method implemented in the HW to counter WLAN RX > sensitivity degradation when BT is transmitting at the same time. This feature is supported by cards like WB222 based on AR9462. iwlwifi: * Location Aware Regulatory was added by Arik * 8000 device family work * update to the BT Coex firmware API brmcfmac: * add new BCM43455 and BCM43457 SDIO device support * add new BCM43430 SDIO device support wil6210: * take care of AP bridging * fix NAPI behavior * found approach to achieve 4*n+2 alignment of Rx frames rt2x00: * add new rt2800usb device DWA 130 rtlwifi: * add USB ID for D-Link DWA-131 * add USB ID ASUS N10 WiFi dongle mwifiex: * throughput enhancements ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/11n.c18
-rw-r--r--drivers/net/wireless/mwifiex/11n.h32
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c16
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c7
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c167
-rw-r--r--drivers/net/wireless/mwifiex/decl.h10
-rw-r--r--drivers/net/wireless/mwifiex/fw.h11
-rw-r--r--drivers/net/wireless/mwifiex/init.c26
-rw-r--r--drivers/net/wireless/mwifiex/main.c76
-rw-r--r--drivers/net/wireless/mwifiex/main.h30
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c31
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c226
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h14
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c61
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c21
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c4
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c128
-rw-r--r--drivers/net/wireless/mwifiex/usb.c6
-rw-r--r--drivers/net/wireless/mwifiex/util.c4
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c48
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h2
21 files changed, 714 insertions, 224 deletions
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 543148d27b01..433bd6837c79 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -159,6 +159,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
159 int tid; 159 int tid;
160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; 160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp;
161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; 161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
162 struct mwifiex_ra_list_tbl *ra_list;
162 u16 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); 163 u16 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
163 164
164 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) 165 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
@@ -166,7 +167,13 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
166 167
167 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) 168 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
168 >> BLOCKACKPARAM_TID_POS; 169 >> BLOCKACKPARAM_TID_POS;
170 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, add_ba_rsp->
171 peer_mac_addr);
169 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) { 172 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
173 if (ra_list) {
174 ra_list->ba_status = BA_SETUP_NONE;
175 ra_list->amsdu_in_ampdu = false;
176 }
170 mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, 177 mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr,
171 TYPE_DELBA_SENT, true); 178 TYPE_DELBA_SENT, true);
172 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) 179 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
@@ -185,6 +192,10 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
185 tx_ba_tbl->amsdu = true; 192 tx_ba_tbl->amsdu = true;
186 else 193 else
187 tx_ba_tbl->amsdu = false; 194 tx_ba_tbl->amsdu = false;
195 if (ra_list) {
196 ra_list->amsdu_in_ampdu = tx_ba_tbl->amsdu;
197 ra_list->ba_status = BA_SETUP_COMPLETE;
198 }
188 } else { 199 } else {
189 dev_err(priv->adapter->dev, "BA stream not created\n"); 200 dev_err(priv->adapter->dev, "BA stream not created\n");
190 } 201 }
@@ -515,6 +526,7 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
515 enum mwifiex_ba_status ba_status) 526 enum mwifiex_ba_status ba_status)
516{ 527{
517 struct mwifiex_tx_ba_stream_tbl *new_node; 528 struct mwifiex_tx_ba_stream_tbl *new_node;
529 struct mwifiex_ra_list_tbl *ra_list;
518 unsigned long flags; 530 unsigned long flags;
519 531
520 if (!mwifiex_get_ba_tbl(priv, tid, ra)) { 532 if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
@@ -522,7 +534,11 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
522 GFP_ATOMIC); 534 GFP_ATOMIC);
523 if (!new_node) 535 if (!new_node)
524 return; 536 return;
525 537 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra);
538 if (ra_list) {
539 ra_list->ba_status = ba_status;
540 ra_list->amsdu_in_ampdu = false;
541 }
526 INIT_LIST_HEAD(&new_node->list); 542 INIT_LIST_HEAD(&new_node->list);
527 543
528 new_node->tid = tid; 544 new_node->tid = tid;
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 8e2e39422ad8..afdd58aa90de 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -77,22 +77,6 @@ mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
77 return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false; 77 return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false;
78} 78}
79 79
80/* This function checks whether AMSDU is allowed for BA stream. */
81static inline u8
82mwifiex_is_amsdu_in_ampdu_allowed(struct mwifiex_private *priv,
83 struct mwifiex_ra_list_tbl *ptr, int tid)
84{
85 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
86
87 if (is_broadcast_ether_addr(ptr->ra))
88 return false;
89 tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
90 if (tx_tbl)
91 return tx_tbl->amsdu;
92
93 return false;
94}
95
96/* This function checks whether AMPDU is allowed or not for a particular TID. */ 80/* This function checks whether AMPDU is allowed or not for a particular TID. */
97static inline u8 81static inline u8
98mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, 82mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
@@ -182,22 +166,6 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
182} 166}
183 167
184/* 168/*
185 * This function checks whether BA stream is set up or not.
186 */
187static inline int
188mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
189 struct mwifiex_ra_list_tbl *ptr, int tid)
190{
191 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
192
193 tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
194 if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
195 return true;
196
197 return false;
198}
199
200/*
201 * This function checks whether associated station is 11n enabled 169 * This function checks whether associated station is 11n enabled
202 */ 170 */
203static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv, 171static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 9b983b5cebbd..6183e255e62a 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -170,7 +170,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
170 struct mwifiex_adapter *adapter = priv->adapter; 170 struct mwifiex_adapter *adapter = priv->adapter;
171 struct sk_buff *skb_aggr, *skb_src; 171 struct sk_buff *skb_aggr, *skb_src;
172 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src; 172 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
173 int pad = 0, ret; 173 int pad = 0, aggr_num = 0, ret;
174 struct mwifiex_tx_param tx_param; 174 struct mwifiex_tx_param tx_param;
175 struct txpd *ptx_pd = NULL; 175 struct txpd *ptx_pd = NULL;
176 struct timeval tv; 176 struct timeval tv;
@@ -184,7 +184,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
184 } 184 }
185 185
186 tx_info_src = MWIFIEX_SKB_TXCB(skb_src); 186 tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
187 skb_aggr = dev_alloc_skb(adapter->tx_buf_size); 187 skb_aggr = mwifiex_alloc_dma_align_buf(adapter->tx_buf_size,
188 GFP_ATOMIC | GFP_DMA);
188 if (!skb_aggr) { 189 if (!skb_aggr) {
189 dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__); 190 dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
190 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 191 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
@@ -200,6 +201,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
200 201
201 if (tx_info_src->flags & MWIFIEX_BUF_FLAG_TDLS_PKT) 202 if (tx_info_src->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
202 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 203 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
204 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_AGGR_PKT;
203 skb_aggr->priority = skb_src->priority; 205 skb_aggr->priority = skb_src->priority;
204 206
205 do_gettimeofday(&tv); 207 do_gettimeofday(&tv);
@@ -211,11 +213,9 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
211 break; 213 break;
212 214
213 skb_src = skb_dequeue(&pra_list->skb_head); 215 skb_src = skb_dequeue(&pra_list->skb_head);
214
215 pra_list->total_pkt_count--; 216 pra_list->total_pkt_count--;
216
217 atomic_dec(&priv->wmm.tx_pkts_queued); 217 atomic_dec(&priv->wmm.tx_pkts_queued);
218 218 aggr_num++;
219 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 219 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
220 ra_list_flags); 220 ra_list_flags);
221 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); 221 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
@@ -251,6 +251,12 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
251 ptx_pd = (struct txpd *)skb_aggr->data; 251 ptx_pd = (struct txpd *)skb_aggr->data;
252 252
253 skb_push(skb_aggr, headroom); 253 skb_push(skb_aggr, headroom);
254 tx_info_aggr->aggr_num = aggr_num * 2;
255 if (adapter->data_sent || adapter->tx_lock_flag) {
256 atomic_add(aggr_num * 2, &adapter->tx_queued);
257 skb_queue_tail(&adapter->tx_data_q, skb_aggr);
258 return 0;
259 }
254 260
255 if (adapter->iface_type == MWIFIEX_USB) { 261 if (adapter->iface_type == MWIFIEX_USB) {
256 adapter->data_sent = true; 262 adapter->data_sent = true;
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index a2e8817b56d8..f75f8acfaca0 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -659,6 +659,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
659{ 659{
660 struct mwifiex_rx_reorder_tbl *tbl; 660 struct mwifiex_rx_reorder_tbl *tbl;
661 struct mwifiex_tx_ba_stream_tbl *ptx_tbl; 661 struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
662 struct mwifiex_ra_list_tbl *ra_list;
662 u8 cleanup_rx_reorder_tbl; 663 u8 cleanup_rx_reorder_tbl;
663 unsigned long flags; 664 unsigned long flags;
664 665
@@ -686,7 +687,11 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
686 "event: TID, RA not found in table\n"); 687 "event: TID, RA not found in table\n");
687 return; 688 return;
688 } 689 }
689 690 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, peer_mac);
691 if (ra_list) {
692 ra_list->amsdu_in_ampdu = false;
693 ra_list->ba_status = BA_SETUP_NONE;
694 }
690 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); 695 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
691 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl); 696 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl);
692 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); 697 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 6f8993c12373..bf9020ff2d33 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -717,6 +717,9 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
717 717
718static int mwifiex_deinit_priv_params(struct mwifiex_private *priv) 718static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
719{ 719{
720 struct mwifiex_adapter *adapter = priv->adapter;
721 unsigned long flags;
722
720 priv->mgmt_frame_mask = 0; 723 priv->mgmt_frame_mask = 0;
721 if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG, 724 if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
722 HostCmd_ACT_GEN_SET, 0, 725 HostCmd_ACT_GEN_SET, 0,
@@ -727,6 +730,25 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
727 } 730 }
728 731
729 mwifiex_deauthenticate(priv, NULL); 732 mwifiex_deauthenticate(priv, NULL);
733
734 spin_lock_irqsave(&adapter->main_proc_lock, flags);
735 adapter->main_locked = true;
736 if (adapter->mwifiex_processing) {
737 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
738 flush_workqueue(adapter->workqueue);
739 } else {
740 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
741 }
742
743 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
744 adapter->rx_locked = true;
745 if (adapter->rx_processing) {
746 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
747 flush_workqueue(adapter->rx_workqueue);
748 } else {
749 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
750 }
751
730 mwifiex_free_priv(priv); 752 mwifiex_free_priv(priv);
731 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; 753 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
732 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 754 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -740,6 +762,9 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
740 struct net_device *dev, 762 struct net_device *dev,
741 enum nl80211_iftype type) 763 enum nl80211_iftype type)
742{ 764{
765 struct mwifiex_adapter *adapter = priv->adapter;
766 unsigned long flags;
767
743 mwifiex_init_priv(priv); 768 mwifiex_init_priv(priv);
744 769
745 priv->bss_mode = type; 770 priv->bss_mode = type;
@@ -770,6 +795,14 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
770 return -EOPNOTSUPP; 795 return -EOPNOTSUPP;
771 } 796 }
772 797
798 spin_lock_irqsave(&adapter->main_proc_lock, flags);
799 adapter->main_locked = false;
800 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
801
802 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
803 adapter->rx_locked = false;
804 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
805
773 return 0; 806 return 0;
774} 807}
775 808
@@ -2733,24 +2766,71 @@ mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
2733} 2766}
2734 2767
2735#ifdef CONFIG_PM 2768#ifdef CONFIG_PM
2736static int mwifiex_set_mef_filter(struct mwifiex_private *priv, 2769static void mwifiex_set_auto_arp_mef_entry(struct mwifiex_private *priv,
2737 struct cfg80211_wowlan *wowlan) 2770 struct mwifiex_mef_entry *mef_entry)
2771{
2772 int i, filt_num = 0, num_ipv4 = 0;
2773 struct in_device *in_dev;
2774 struct in_ifaddr *ifa;
2775 __be32 ips[MWIFIEX_MAX_SUPPORTED_IPADDR];
2776 struct mwifiex_adapter *adapter = priv->adapter;
2777
2778 mef_entry->mode = MEF_MODE_HOST_SLEEP;
2779 mef_entry->action = MEF_ACTION_AUTO_ARP;
2780
2781 /* Enable ARP offload feature */
2782 memset(ips, 0, sizeof(ips));
2783 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
2784 if (adapter->priv[i]->netdev) {
2785 in_dev = __in_dev_get_rtnl(adapter->priv[i]->netdev);
2786 if (!in_dev)
2787 continue;
2788 ifa = in_dev->ifa_list;
2789 if (!ifa || !ifa->ifa_local)
2790 continue;
2791 ips[i] = ifa->ifa_local;
2792 num_ipv4++;
2793 }
2794 }
2795
2796 for (i = 0; i < num_ipv4; i++) {
2797 if (!ips[i])
2798 continue;
2799 mef_entry->filter[filt_num].repeat = 1;
2800 memcpy(mef_entry->filter[filt_num].byte_seq,
2801 (u8 *)&ips[i], sizeof(ips[i]));
2802 mef_entry->filter[filt_num].
2803 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2804 sizeof(ips[i]);
2805 mef_entry->filter[filt_num].offset = 46;
2806 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2807 if (filt_num) {
2808 mef_entry->filter[filt_num].filt_action =
2809 TYPE_OR;
2810 }
2811 filt_num++;
2812 }
2813
2814 mef_entry->filter[filt_num].repeat = 1;
2815 mef_entry->filter[filt_num].byte_seq[0] = 0x08;
2816 mef_entry->filter[filt_num].byte_seq[1] = 0x06;
2817 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2;
2818 mef_entry->filter[filt_num].offset = 20;
2819 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2820 mef_entry->filter[filt_num].filt_action = TYPE_AND;
2821}
2822
2823static int mwifiex_set_wowlan_mef_entry(struct mwifiex_private *priv,
2824 struct mwifiex_ds_mef_cfg *mef_cfg,
2825 struct mwifiex_mef_entry *mef_entry,
2826 struct cfg80211_wowlan *wowlan)
2738{ 2827{
2739 int i, filt_num = 0, ret = 0; 2828 int i, filt_num = 0, ret = 0;
2740 bool first_pat = true; 2829 bool first_pat = true;
2741 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1]; 2830 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
2742 const u8 ipv4_mc_mac[] = {0x33, 0x33}; 2831 const u8 ipv4_mc_mac[] = {0x33, 0x33};
2743 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e}; 2832 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2744 struct mwifiex_ds_mef_cfg mef_cfg;
2745 struct mwifiex_mef_entry *mef_entry;
2746 2833
2747 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
2748 if (!mef_entry)
2749 return -ENOMEM;
2750
2751 memset(&mef_cfg, 0, sizeof(mef_cfg));
2752 mef_cfg.num_entries = 1;
2753 mef_cfg.mef_entry = mef_entry;
2754 mef_entry->mode = MEF_MODE_HOST_SLEEP; 2834 mef_entry->mode = MEF_MODE_HOST_SLEEP;
2755 mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST; 2835 mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
2756 2836
@@ -2767,20 +2847,19 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2767 if (!wowlan->patterns[i].pkt_offset) { 2847 if (!wowlan->patterns[i].pkt_offset) {
2768 if (!(byte_seq[0] & 0x01) && 2848 if (!(byte_seq[0] & 0x01) &&
2769 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 1)) { 2849 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 1)) {
2770 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; 2850 mef_cfg->criteria |= MWIFIEX_CRITERIA_UNICAST;
2771 continue; 2851 continue;
2772 } else if (is_broadcast_ether_addr(byte_seq)) { 2852 } else if (is_broadcast_ether_addr(byte_seq)) {
2773 mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST; 2853 mef_cfg->criteria |= MWIFIEX_CRITERIA_BROADCAST;
2774 continue; 2854 continue;
2775 } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) && 2855 } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
2776 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 2)) || 2856 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 2)) ||
2777 (!memcmp(byte_seq, ipv6_mc_mac, 3) && 2857 (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
2778 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 3))) { 2858 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 3))) {
2779 mef_cfg.criteria |= MWIFIEX_CRITERIA_MULTICAST; 2859 mef_cfg->criteria |= MWIFIEX_CRITERIA_MULTICAST;
2780 continue; 2860 continue;
2781 } 2861 }
2782 } 2862 }
2783
2784 mef_entry->filter[filt_num].repeat = 1; 2863 mef_entry->filter[filt_num].repeat = 1;
2785 mef_entry->filter[filt_num].offset = 2864 mef_entry->filter[filt_num].offset =
2786 wowlan->patterns[i].pkt_offset; 2865 wowlan->patterns[i].pkt_offset;
@@ -2797,7 +2876,7 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2797 } 2876 }
2798 2877
2799 if (wowlan->magic_pkt) { 2878 if (wowlan->magic_pkt) {
2800 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; 2879 mef_cfg->criteria |= MWIFIEX_CRITERIA_UNICAST;
2801 mef_entry->filter[filt_num].repeat = 16; 2880 mef_entry->filter[filt_num].repeat = 16;
2802 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, 2881 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2803 ETH_ALEN); 2882 ETH_ALEN);
@@ -2818,6 +2897,34 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2818 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2897 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2819 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2898 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2820 } 2899 }
2900 return ret;
2901}
2902
2903static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2904 struct cfg80211_wowlan *wowlan)
2905{
2906 int ret = 0, num_entries = 1;
2907 struct mwifiex_ds_mef_cfg mef_cfg;
2908 struct mwifiex_mef_entry *mef_entry;
2909
2910 if (wowlan->n_patterns || wowlan->magic_pkt)
2911 num_entries++;
2912
2913 mef_entry = kcalloc(num_entries, sizeof(*mef_entry), GFP_KERNEL);
2914 if (!mef_entry)
2915 return -ENOMEM;
2916
2917 memset(&mef_cfg, 0, sizeof(mef_cfg));
2918 mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST |
2919 MWIFIEX_CRITERIA_UNICAST;
2920 mef_cfg.num_entries = num_entries;
2921 mef_cfg.mef_entry = mef_entry;
2922
2923 mwifiex_set_auto_arp_mef_entry(priv, &mef_entry[0]);
2924
2925 if (wowlan->n_patterns || wowlan->magic_pkt)
2926 ret = mwifiex_set_wowlan_mef_entry(priv, &mef_cfg,
2927 &mef_entry[1], wowlan);
2821 2928
2822 if (!mef_cfg.criteria) 2929 if (!mef_cfg.criteria)
2823 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST | 2930 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
@@ -2825,8 +2932,8 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2825 MWIFIEX_CRITERIA_MULTICAST; 2932 MWIFIEX_CRITERIA_MULTICAST;
2826 2933
2827 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG, 2934 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2828 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true); 2935 HostCmd_ACT_GEN_SET, 0,
2829 2936 &mef_cfg, true);
2830 kfree(mef_entry); 2937 kfree(mef_entry);
2831 return ret; 2938 return ret;
2832} 2939}
@@ -2836,27 +2943,33 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2836{ 2943{
2837 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 2944 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2838 struct mwifiex_ds_hs_cfg hs_cfg; 2945 struct mwifiex_ds_hs_cfg hs_cfg;
2839 int ret = 0; 2946 int i, ret = 0;
2840 struct mwifiex_private *priv = 2947 struct mwifiex_private *priv;
2841 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); 2948
2949 for (i = 0; i < adapter->priv_num; i++) {
2950 priv = adapter->priv[i];
2951 mwifiex_abort_cac(priv);
2952 }
2953
2954 mwifiex_cancel_all_pending_cmd(adapter);
2842 2955
2843 if (!wowlan) { 2956 if (!wowlan) {
2844 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n"); 2957 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2845 return 0; 2958 return 0;
2846 } 2959 }
2847 2960
2961 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2962
2848 if (!priv->media_connected) { 2963 if (!priv->media_connected) {
2849 dev_warn(adapter->dev, 2964 dev_warn(adapter->dev,
2850 "Can not configure WOWLAN in disconnected state\n"); 2965 "Can not configure WOWLAN in disconnected state\n");
2851 return 0; 2966 return 0;
2852 } 2967 }
2853 2968
2854 if (wowlan->n_patterns || wowlan->magic_pkt) { 2969 ret = mwifiex_set_mef_filter(priv, wowlan);
2855 ret = mwifiex_set_mef_filter(priv, wowlan); 2970 if (ret) {
2856 if (ret) { 2971 dev_err(adapter->dev, "Failed to set MEF filter\n");
2857 dev_err(adapter->dev, "Failed to set MEF filter\n"); 2972 return ret;
2858 return ret;
2859 }
2860 } 2973 }
2861 2974
2862 if (wowlan->disconnect) { 2975 if (wowlan->disconnect) {
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index cf2fa110e251..38f24e0427d2 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -83,6 +83,7 @@
83#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2) 83#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
84#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3) 84#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
85#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4) 85#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4)
86#define MWIFIEX_BUF_FLAG_AGGR_PKT BIT(5)
86 87
87#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 88#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
88#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 89#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
@@ -111,6 +112,11 @@
111 112
112#define MWIFIEX_A_BAND_START_FREQ 5000 113#define MWIFIEX_A_BAND_START_FREQ 5000
113 114
115/* SDIO Aggr data packet special info */
116#define SDIO_MAX_AGGR_BUF_SIZE (256 * 255)
117#define BLOCK_NUMBER_OFFSET 15
118#define SDIO_HEADER_OFFSET 28
119
114enum mwifiex_bss_type { 120enum mwifiex_bss_type {
115 MWIFIEX_BSS_TYPE_STA = 0, 121 MWIFIEX_BSS_TYPE_STA = 0,
116 MWIFIEX_BSS_TYPE_UAP = 1, 122 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -168,10 +174,11 @@ struct mwifiex_wait_queue {
168}; 174};
169 175
170struct mwifiex_rxinfo { 176struct mwifiex_rxinfo {
177 struct sk_buff *parent;
171 u8 bss_num; 178 u8 bss_num;
172 u8 bss_type; 179 u8 bss_type;
173 struct sk_buff *parent;
174 u8 use_count; 180 u8 use_count;
181 u8 buf_type;
175}; 182};
176 183
177struct mwifiex_txinfo { 184struct mwifiex_txinfo {
@@ -179,6 +186,7 @@ struct mwifiex_txinfo {
179 u8 flags; 186 u8 flags;
180 u8 bss_num; 187 u8 bss_num;
181 u8 bss_type; 188 u8 bss_type;
189 u8 aggr_num;
182 u32 pkt_len; 190 u32 pkt_len;
183 u8 ack_frame_id; 191 u8 ack_frame_id;
184 u64 cookie; 192 u64 cookie;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index df553e86a0ad..59d8964dd0dc 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -197,6 +197,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
197 197
198#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) 198#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
199#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14)) 199#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
200#define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16))
200 201
201#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ 202#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
202 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ 203 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
@@ -353,6 +354,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
353#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d 354#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d
354#define HostCmd_CMD_11AC_CFG 0x0112 355#define HostCmd_CMD_11AC_CFG 0x0112
355#define HostCmd_CMD_TDLS_OPER 0x0122 356#define HostCmd_CMD_TDLS_OPER 0x0122
357#define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG 0x0223
356 358
357#define PROTOCOL_NO_SECURITY 0x01 359#define PROTOCOL_NO_SECURITY 0x01
358#define PROTOCOL_STATIC_WEP 0x02 360#define PROTOCOL_STATIC_WEP 0x02
@@ -523,9 +525,11 @@ enum P2P_MODES {
523#define TYPE_OR (MAX_OPERAND+5) 525#define TYPE_OR (MAX_OPERAND+5)
524#define MEF_MODE_HOST_SLEEP 1 526#define MEF_MODE_HOST_SLEEP 1
525#define MEF_ACTION_ALLOW_AND_WAKEUP_HOST 3 527#define MEF_ACTION_ALLOW_AND_WAKEUP_HOST 3
528#define MEF_ACTION_AUTO_ARP 0x10
526#define MWIFIEX_CRITERIA_BROADCAST BIT(0) 529#define MWIFIEX_CRITERIA_BROADCAST BIT(0)
527#define MWIFIEX_CRITERIA_UNICAST BIT(1) 530#define MWIFIEX_CRITERIA_UNICAST BIT(1)
528#define MWIFIEX_CRITERIA_MULTICAST BIT(3) 531#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
532#define MWIFIEX_MAX_SUPPORTED_IPADDR 4
529 533
530#define ACT_TDLS_DELETE 0x00 534#define ACT_TDLS_DELETE 0x00
531#define ACT_TDLS_CREATE 0x01 535#define ACT_TDLS_CREATE 0x01
@@ -1240,6 +1244,12 @@ struct host_cmd_ds_chan_rpt_event {
1240 u8 tlvbuf[0]; 1244 u8 tlvbuf[0];
1241} __packed; 1245} __packed;
1242 1246
1247struct host_cmd_sdio_sp_rx_aggr_cfg {
1248 u8 action;
1249 u8 enable;
1250 __le16 block_size;
1251} __packed;
1252
1243struct mwifiex_fixed_bcn_param { 1253struct mwifiex_fixed_bcn_param {
1244 __le64 timestamp; 1254 __le64 timestamp;
1245 __le16 beacon_period; 1255 __le16 beacon_period;
@@ -1962,6 +1972,7 @@ struct host_cmd_ds_command {
1962 struct host_cmd_ds_coalesce_cfg coalesce_cfg; 1972 struct host_cmd_ds_coalesce_cfg coalesce_cfg;
1963 struct host_cmd_ds_tdls_oper tdls_oper; 1973 struct host_cmd_ds_tdls_oper tdls_oper;
1964 struct host_cmd_ds_chan_rpt_req chan_rpt_req; 1974 struct host_cmd_ds_chan_rpt_req chan_rpt_req;
1975 struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg;
1965 } params; 1976 } params;
1966} __packed; 1977} __packed;
1967 1978
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 0153ce6d5879..e12192f5cfad 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -266,18 +266,15 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
266 266
267 mwifiex_wmm_init(adapter); 267 mwifiex_wmm_init(adapter);
268 268
269 if (adapter->sleep_cfm) { 269 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
270 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) 270 adapter->sleep_cfm->data;
271 adapter->sleep_cfm->data; 271 memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
272 memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); 272 sleep_cfm_buf->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
273 sleep_cfm_buf->command = 273 sleep_cfm_buf->size = cpu_to_le16(adapter->sleep_cfm->len);
274 cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); 274 sleep_cfm_buf->result = 0;
275 sleep_cfm_buf->size = 275 sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
276 cpu_to_le16(adapter->sleep_cfm->len); 276 sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
277 sleep_cfm_buf->result = 0; 277
278 sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
279 sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
280 }
281 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params)); 278 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
282 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period)); 279 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
283 adapter->tx_lock_flag = false; 280 adapter->tx_lock_flag = false;
@@ -481,6 +478,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
481 spin_lock_init(&adapter->rx_proc_lock); 478 spin_lock_init(&adapter->rx_proc_lock);
482 479
483 skb_queue_head_init(&adapter->rx_data_q); 480 skb_queue_head_init(&adapter->rx_data_q);
481 skb_queue_head_init(&adapter->tx_data_q);
484 482
485 for (i = 0; i < adapter->priv_num; ++i) { 483 for (i = 0; i < adapter->priv_num; ++i) {
486 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); 484 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
@@ -688,6 +686,10 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
688 } 686 }
689 } 687 }
690 688
689 atomic_set(&adapter->tx_queued, 0);
690 while ((skb = skb_dequeue(&adapter->tx_data_q)))
691 mwifiex_write_data_complete(adapter, skb, 0, 0);
692
691 spin_lock_irqsave(&adapter->rx_proc_lock, flags); 693 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
692 694
693 while ((skb = skb_dequeue(&adapter->rx_data_q))) { 695 while ((skb = skb_dequeue(&adapter->rx_data_q))) {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index d73a9217b9da..03a95c7d34bf 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -131,10 +131,39 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
131 return 0; 131 return 0;
132} 132}
133 133
134void mwifiex_queue_main_work(struct mwifiex_adapter *adapter)
135{
136 unsigned long flags;
137
138 spin_lock_irqsave(&adapter->main_proc_lock, flags);
139 if (adapter->mwifiex_processing) {
140 adapter->more_task_flag = true;
141 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
142 } else {
143 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
144 queue_work(adapter->workqueue, &adapter->main_work);
145 }
146}
147EXPORT_SYMBOL_GPL(mwifiex_queue_main_work);
148
149static void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter)
150{
151 unsigned long flags;
152
153 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
154 if (adapter->rx_processing) {
155 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
156 } else {
157 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
158 queue_work(adapter->rx_workqueue, &adapter->rx_work);
159 }
160}
161
134static int mwifiex_process_rx(struct mwifiex_adapter *adapter) 162static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
135{ 163{
136 unsigned long flags; 164 unsigned long flags;
137 struct sk_buff *skb; 165 struct sk_buff *skb;
166 struct mwifiex_rxinfo *rx_info;
138 167
139 spin_lock_irqsave(&adapter->rx_proc_lock, flags); 168 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
140 if (adapter->rx_processing || adapter->rx_locked) { 169 if (adapter->rx_processing || adapter->rx_locked) {
@@ -154,9 +183,16 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
154 if (adapter->if_ops.submit_rem_rx_urbs) 183 if (adapter->if_ops.submit_rem_rx_urbs)
155 adapter->if_ops.submit_rem_rx_urbs(adapter); 184 adapter->if_ops.submit_rem_rx_urbs(adapter);
156 adapter->delay_main_work = false; 185 adapter->delay_main_work = false;
157 queue_work(adapter->workqueue, &adapter->main_work); 186 mwifiex_queue_main_work(adapter);
187 }
188 rx_info = MWIFIEX_SKB_RXCB(skb);
189 if (rx_info->buf_type == MWIFIEX_TYPE_AGGR_DATA) {
190 if (adapter->if_ops.deaggr_pkt)
191 adapter->if_ops.deaggr_pkt(adapter, skb);
192 dev_kfree_skb_any(skb);
193 } else {
194 mwifiex_handle_rx_packet(adapter, skb);
158 } 195 }
159 mwifiex_handle_rx_packet(adapter, skb);
160 } 196 }
161 spin_lock_irqsave(&adapter->rx_proc_lock, flags); 197 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
162 adapter->rx_processing = false; 198 adapter->rx_processing = false;
@@ -189,7 +225,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
189 spin_lock_irqsave(&adapter->main_proc_lock, flags); 225 spin_lock_irqsave(&adapter->main_proc_lock, flags);
190 226
191 /* Check if already processing */ 227 /* Check if already processing */
192 if (adapter->mwifiex_processing) { 228 if (adapter->mwifiex_processing || adapter->main_locked) {
193 adapter->more_task_flag = true; 229 adapter->more_task_flag = true;
194 spin_unlock_irqrestore(&adapter->main_proc_lock, flags); 230 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
195 goto exit_main_proc; 231 goto exit_main_proc;
@@ -214,9 +250,7 @@ process_start:
214 if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING && 250 if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING &&
215 adapter->iface_type != MWIFIEX_USB) { 251 adapter->iface_type != MWIFIEX_USB) {
216 adapter->delay_main_work = true; 252 adapter->delay_main_work = true;
217 if (!adapter->rx_processing) 253 mwifiex_queue_rx_work(adapter);
218 queue_work(adapter->rx_workqueue,
219 &adapter->rx_work);
220 break; 254 break;
221 } 255 }
222 256
@@ -229,13 +263,14 @@ process_start:
229 } 263 }
230 264
231 if (adapter->rx_work_enabled && adapter->data_received) 265 if (adapter->rx_work_enabled && adapter->data_received)
232 queue_work(adapter->rx_workqueue, &adapter->rx_work); 266 mwifiex_queue_rx_work(adapter);
233 267
234 /* Need to wake up the card ? */ 268 /* Need to wake up the card ? */
235 if ((adapter->ps_state == PS_STATE_SLEEP) && 269 if ((adapter->ps_state == PS_STATE_SLEEP) &&
236 (adapter->pm_wakeup_card_req && 270 (adapter->pm_wakeup_card_req &&
237 !adapter->pm_wakeup_fw_try) && 271 !adapter->pm_wakeup_fw_try) &&
238 (is_command_pending(adapter) || 272 (is_command_pending(adapter) ||
273 !skb_queue_empty(&adapter->tx_data_q) ||
239 !mwifiex_wmm_lists_empty(adapter))) { 274 !mwifiex_wmm_lists_empty(adapter))) {
240 adapter->pm_wakeup_fw_try = true; 275 adapter->pm_wakeup_fw_try = true;
241 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3)); 276 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
@@ -247,7 +282,7 @@ process_start:
247 if (IS_CARD_RX_RCVD(adapter)) { 282 if (IS_CARD_RX_RCVD(adapter)) {
248 adapter->data_received = false; 283 adapter->data_received = false;
249 adapter->pm_wakeup_fw_try = false; 284 adapter->pm_wakeup_fw_try = false;
250 del_timer_sync(&adapter->wakeup_timer); 285 del_timer(&adapter->wakeup_timer);
251 if (adapter->ps_state == PS_STATE_SLEEP) 286 if (adapter->ps_state == PS_STATE_SLEEP)
252 adapter->ps_state = PS_STATE_AWAKE; 287 adapter->ps_state = PS_STATE_AWAKE;
253 } else { 288 } else {
@@ -260,7 +295,8 @@ process_start:
260 295
261 if ((!adapter->scan_chan_gap_enabled && 296 if ((!adapter->scan_chan_gap_enabled &&
262 adapter->scan_processing) || adapter->data_sent || 297 adapter->scan_processing) || adapter->data_sent ||
263 mwifiex_wmm_lists_empty(adapter)) { 298 (mwifiex_wmm_lists_empty(adapter) &&
299 skb_queue_empty(&adapter->tx_data_q))) {
264 if (adapter->cmd_sent || adapter->curr_cmd || 300 if (adapter->cmd_sent || adapter->curr_cmd ||
265 (!is_command_pending(adapter))) 301 (!is_command_pending(adapter)))
266 break; 302 break;
@@ -312,6 +348,20 @@ process_start:
312 348
313 if ((adapter->scan_chan_gap_enabled || 349 if ((adapter->scan_chan_gap_enabled ||
314 !adapter->scan_processing) && 350 !adapter->scan_processing) &&
351 !adapter->data_sent &&
352 !skb_queue_empty(&adapter->tx_data_q)) {
353 mwifiex_process_tx_queue(adapter);
354 if (adapter->hs_activated) {
355 adapter->is_hs_configured = false;
356 mwifiex_hs_activated_event
357 (mwifiex_get_priv
358 (adapter, MWIFIEX_BSS_ROLE_ANY),
359 false);
360 }
361 }
362
363 if ((adapter->scan_chan_gap_enabled ||
364 !adapter->scan_processing) &&
315 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { 365 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
316 mwifiex_wmm_process_tx(adapter); 366 mwifiex_wmm_process_tx(adapter);
317 if (adapter->hs_activated) { 367 if (adapter->hs_activated) {
@@ -325,7 +375,8 @@ process_start:
325 375
326 if (adapter->delay_null_pkt && !adapter->cmd_sent && 376 if (adapter->delay_null_pkt && !adapter->cmd_sent &&
327 !adapter->curr_cmd && !is_command_pending(adapter) && 377 !adapter->curr_cmd && !is_command_pending(adapter) &&
328 mwifiex_wmm_lists_empty(adapter)) { 378 (mwifiex_wmm_lists_empty(adapter) &&
379 skb_queue_empty(&adapter->tx_data_q))) {
329 if (!mwifiex_send_null_packet 380 if (!mwifiex_send_null_packet
330 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), 381 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
331 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | 382 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
@@ -606,7 +657,7 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
606 atomic_inc(&priv->adapter->tx_pending); 657 atomic_inc(&priv->adapter->tx_pending);
607 mwifiex_wmm_add_buf_txqueue(priv, skb); 658 mwifiex_wmm_add_buf_txqueue(priv, skb);
608 659
609 queue_work(priv->adapter->workqueue, &priv->adapter->main_work); 660 mwifiex_queue_main_work(priv->adapter);
610 661
611 return 0; 662 return 0;
612} 663}
@@ -1098,9 +1149,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
1098 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue); 1149 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
1099 } 1150 }
1100 1151
1101 if (adapter->if_ops.iface_work)
1102 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
1103
1104 /* Register the device. Fill up the private data structure with relevant 1152 /* Register the device. Fill up the private data structure with relevant
1105 information from the card. */ 1153 information from the card. */
1106 if (adapter->if_ops.register_dev(adapter)) { 1154 if (adapter->if_ops.register_dev(adapter)) {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index ad8db61aeeef..fe1256044a6c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -35,6 +35,7 @@
35#include <linux/ctype.h> 35#include <linux/ctype.h>
36#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/idr.h> 37#include <linux/idr.h>
38#include <linux/inetdevice.h>
38 39
39#include "decl.h" 40#include "decl.h"
40#include "ioctl.h" 41#include "ioctl.h"
@@ -58,6 +59,8 @@ enum {
58 59
59#define MWIFIEX_MAX_AP 64 60#define MWIFIEX_MAX_AP 64
60 61
62#define MWIFIEX_MAX_PKTS_TXQ 16
63
61#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ) 64#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
62 65
63#define MWIFIEX_TIMER_10S 10000 66#define MWIFIEX_TIMER_10S 10000
@@ -118,6 +121,7 @@ enum {
118 121
119#define MWIFIEX_TYPE_CMD 1 122#define MWIFIEX_TYPE_CMD 1
120#define MWIFIEX_TYPE_DATA 0 123#define MWIFIEX_TYPE_DATA 0
124#define MWIFIEX_TYPE_AGGR_DATA 10
121#define MWIFIEX_TYPE_EVENT 3 125#define MWIFIEX_TYPE_EVENT 3
122 126
123#define MAX_BITMAP_RATES_SIZE 18 127#define MAX_BITMAP_RATES_SIZE 18
@@ -210,6 +214,12 @@ struct mwifiex_tx_aggr {
210 u8 amsdu; 214 u8 amsdu;
211}; 215};
212 216
217enum mwifiex_ba_status {
218 BA_SETUP_NONE = 0,
219 BA_SETUP_INPROGRESS,
220 BA_SETUP_COMPLETE
221};
222
213struct mwifiex_ra_list_tbl { 223struct mwifiex_ra_list_tbl {
214 struct list_head list; 224 struct list_head list;
215 struct sk_buff_head skb_head; 225 struct sk_buff_head skb_head;
@@ -218,6 +228,8 @@ struct mwifiex_ra_list_tbl {
218 u16 max_amsdu; 228 u16 max_amsdu;
219 u16 ba_pkt_count; 229 u16 ba_pkt_count;
220 u8 ba_packet_thr; 230 u8 ba_packet_thr;
231 enum mwifiex_ba_status ba_status;
232 u8 amsdu_in_ampdu;
221 u16 total_pkt_count; 233 u16 total_pkt_count;
222 bool tdls_link; 234 bool tdls_link;
223}; 235};
@@ -601,11 +613,6 @@ struct mwifiex_private {
601 struct mwifiex_11h_intf_state state_11h; 613 struct mwifiex_11h_intf_state state_11h;
602}; 614};
603 615
604enum mwifiex_ba_status {
605 BA_SETUP_NONE = 0,
606 BA_SETUP_INPROGRESS,
607 BA_SETUP_COMPLETE
608};
609 616
610struct mwifiex_tx_ba_stream_tbl { 617struct mwifiex_tx_ba_stream_tbl {
611 struct list_head list; 618 struct list_head list;
@@ -738,6 +745,7 @@ struct mwifiex_if_ops {
738 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 745 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
739 void (*iface_work)(struct work_struct *work); 746 void (*iface_work)(struct work_struct *work);
740 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter); 747 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
748 void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
741}; 749};
742 750
743struct mwifiex_adapter { 751struct mwifiex_adapter {
@@ -771,6 +779,7 @@ struct mwifiex_adapter {
771 bool rx_processing; 779 bool rx_processing;
772 bool delay_main_work; 780 bool delay_main_work;
773 bool rx_locked; 781 bool rx_locked;
782 bool main_locked;
774 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; 783 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
775 /* spin lock for init/shutdown */ 784 /* spin lock for init/shutdown */
776 spinlock_t mwifiex_lock; 785 spinlock_t mwifiex_lock;
@@ -780,6 +789,8 @@ struct mwifiex_adapter {
780 u8 more_task_flag; 789 u8 more_task_flag;
781 u16 tx_buf_size; 790 u16 tx_buf_size;
782 u16 curr_tx_buf_size; 791 u16 curr_tx_buf_size;
792 bool sdio_rx_aggr_enable;
793 u16 sdio_rx_block_size;
783 u32 ioport; 794 u32 ioport;
784 enum MWIFIEX_HARDWARE_STATUS hw_status; 795 enum MWIFIEX_HARDWARE_STATUS hw_status;
785 u16 number_of_antenna; 796 u16 number_of_antenna;
@@ -814,6 +825,8 @@ struct mwifiex_adapter {
814 spinlock_t scan_pending_q_lock; 825 spinlock_t scan_pending_q_lock;
815 /* spin lock for RX processing routine */ 826 /* spin lock for RX processing routine */
816 spinlock_t rx_proc_lock; 827 spinlock_t rx_proc_lock;
828 struct sk_buff_head tx_data_q;
829 atomic_t tx_queued;
817 u32 scan_processing; 830 u32 scan_processing;
818 u16 region_code; 831 u16 region_code;
819 struct mwifiex_802_11d_domain_reg domain_reg; 832 struct mwifiex_802_11d_domain_reg domain_reg;
@@ -885,8 +898,6 @@ struct mwifiex_adapter {
885 bool ext_scan; 898 bool ext_scan;
886 u8 fw_api_ver; 899 u8 fw_api_ver;
887 u8 key_api_major_ver, key_api_minor_ver; 900 u8 key_api_major_ver, key_api_minor_ver;
888 struct work_struct iface_work;
889 unsigned long iface_work_flags;
890 struct memory_type_mapping *mem_type_mapping_tbl; 901 struct memory_type_mapping *mem_type_mapping_tbl;
891 u8 num_mem_types; 902 u8 num_mem_types;
892 u8 curr_mem_idx; 903 u8 curr_mem_idx;
@@ -900,6 +911,8 @@ struct mwifiex_adapter {
900 bool auto_tdls; 911 bool auto_tdls;
901}; 912};
902 913
914void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
915
903int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 916int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
904 917
905void mwifiex_set_trans_start(struct net_device *dev); 918void mwifiex_set_trans_start(struct net_device *dev);
@@ -1422,7 +1435,8 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
1422 u8 rx_rate, u8 ht_info); 1435 u8 rx_rate, u8 ht_info);
1423 1436
1424void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter); 1437void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
1425void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags); 1438void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
1439void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
1426 1440
1427#ifdef CONFIG_DEBUG_FS 1441#ifdef CONFIG_DEBUG_FS
1428void mwifiex_debugfs_init(void); 1442void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4b463c3b9906..bcc7751d883c 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -234,8 +234,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
234 if (!adapter || !adapter->priv_num) 234 if (!adapter || !adapter->priv_num)
235 return; 235 return;
236 236
237 cancel_work_sync(&adapter->iface_work);
238
239 if (user_rmmod) { 237 if (user_rmmod) {
240#ifdef CONFIG_PM_SLEEP 238#ifdef CONFIG_PM_SLEEP
241 if (adapter->is_suspended) 239 if (adapter->is_suspended)
@@ -498,8 +496,8 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
498 496
499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { 497 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
500 /* Allocate skb here so that firmware can DMA data from it */ 498 /* Allocate skb here so that firmware can DMA data from it */
501 skb = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE, 499 skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
502 GFP_KERNEL | GFP_DMA); 500 GFP_KERNEL | GFP_DMA);
503 if (!skb) { 501 if (!skb) {
504 dev_err(adapter->dev, 502 dev_err(adapter->dev,
505 "Unable to allocate skb for RX ring.\n"); 503 "Unable to allocate skb for RX ring.\n");
@@ -1298,8 +1296,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1298 } 1296 }
1299 } 1297 }
1300 1298
1301 skb_tmp = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE, 1299 skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1302 GFP_KERNEL | GFP_DMA); 1300 GFP_KERNEL | GFP_DMA);
1303 if (!skb_tmp) { 1301 if (!skb_tmp) {
1304 dev_err(adapter->dev, 1302 dev_err(adapter->dev,
1305 "Unable to allocate skb.\n"); 1303 "Unable to allocate skb.\n");
@@ -2101,7 +2099,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2101 goto exit; 2099 goto exit;
2102 2100
2103 mwifiex_interrupt_status(adapter); 2101 mwifiex_interrupt_status(adapter);
2104 queue_work(adapter->workqueue, &adapter->main_work); 2102 mwifiex_queue_main_work(adapter);
2105 2103
2106exit: 2104exit:
2107 return IRQ_HANDLED; 2105 return IRQ_HANDLED;
@@ -2373,25 +2371,26 @@ done:
2373 adapter->curr_mem_idx = 0; 2371 adapter->curr_mem_idx = 0;
2374} 2372}
2375 2373
2374static unsigned long iface_work_flags;
2375static struct mwifiex_adapter *save_adapter;
2376static void mwifiex_pcie_work(struct work_struct *work) 2376static void mwifiex_pcie_work(struct work_struct *work)
2377{ 2377{
2378 struct mwifiex_adapter *adapter =
2379 container_of(work, struct mwifiex_adapter, iface_work);
2380
2381 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP, 2378 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2382 &adapter->iface_work_flags)) 2379 &iface_work_flags))
2383 mwifiex_pcie_fw_dump_work(adapter); 2380 mwifiex_pcie_fw_dump_work(save_adapter);
2384} 2381}
2385 2382
2383static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
2386/* This function dumps FW information */ 2384/* This function dumps FW information */
2387static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter) 2385static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2388{ 2386{
2389 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags)) 2387 save_adapter = adapter;
2388 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
2390 return; 2389 return;
2391 2390
2392 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags); 2391 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
2393 2392
2394 schedule_work(&adapter->iface_work); 2393 schedule_work(&pcie_work);
2395} 2394}
2396 2395
2397/* 2396/*
@@ -2619,7 +2618,6 @@ static struct mwifiex_if_ops pcie_ops = {
2619 .init_fw_port = mwifiex_pcie_init_fw_port, 2618 .init_fw_port = mwifiex_pcie_init_fw_port,
2620 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, 2619 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
2621 .fw_dump = mwifiex_pcie_fw_dump, 2620 .fw_dump = mwifiex_pcie_fw_dump,
2622 .iface_work = mwifiex_pcie_work,
2623}; 2621};
2624 2622
2625/* 2623/*
@@ -2665,6 +2663,7 @@ static void mwifiex_pcie_cleanup_module(void)
2665 /* Set the flag as user is removing this module. */ 2663 /* Set the flag as user is removing this module. */
2666 user_rmmod = 1; 2664 user_rmmod = 1;
2667 2665
2666 cancel_work_sync(&pcie_work);
2668 pci_unregister_driver(&mwifiex_pcie); 2667 pci_unregister_driver(&mwifiex_pcie);
2669} 2668}
2670 2669
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 57d85ab442bf..d10320f89bc1 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -47,6 +47,7 @@
47static u8 user_rmmod; 47static u8 user_rmmod;
48 48
49static struct mwifiex_if_ops sdio_ops; 49static struct mwifiex_if_ops sdio_ops;
50static unsigned long iface_work_flags;
50 51
51static struct semaphore add_remove_card_sem; 52static struct semaphore add_remove_card_sem;
52 53
@@ -200,8 +201,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
200 if (!adapter || !adapter->priv_num) 201 if (!adapter || !adapter->priv_num)
201 return; 202 return;
202 203
203 cancel_work_sync(&adapter->iface_work);
204
205 if (user_rmmod) { 204 if (user_rmmod) {
206 if (adapter->is_suspended) 205 if (adapter->is_suspended)
207 mwifiex_sdio_resume(adapter->dev); 206 mwifiex_sdio_resume(adapter->dev);
@@ -1043,6 +1042,59 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
1043} 1042}
1044 1043
1045/* 1044/*
1045 * This function decode sdio aggreation pkt.
1046 *
1047 * Based on the the data block size and pkt_len,
1048 * skb data will be decoded to few packets.
1049 */
1050static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter,
1051 struct sk_buff *skb)
1052{
1053 u32 total_pkt_len, pkt_len;
1054 struct sk_buff *skb_deaggr;
1055 u32 pkt_type;
1056 u16 blk_size;
1057 u8 blk_num;
1058 u8 *data;
1059
1060 data = skb->data;
1061 total_pkt_len = skb->len;
1062
1063 while (total_pkt_len >= (SDIO_HEADER_OFFSET + INTF_HEADER_LEN)) {
1064 if (total_pkt_len < adapter->sdio_rx_block_size)
1065 break;
1066 blk_num = *(data + BLOCK_NUMBER_OFFSET);
1067 blk_size = adapter->sdio_rx_block_size * blk_num;
1068 if (blk_size > total_pkt_len) {
1069 dev_err(adapter->dev, "%s: error in pkt,\t"
1070 "blk_num=%d, blk_size=%d, total_pkt_len=%d\n",
1071 __func__, blk_num, blk_size, total_pkt_len);
1072 break;
1073 }
1074 pkt_len = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET));
1075 pkt_type = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET +
1076 2));
1077 if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) {
1078 dev_err(adapter->dev, "%s: error in pkt,\t"
1079 "pkt_len=%d, blk_size=%d\n",
1080 __func__, pkt_len, blk_size);
1081 break;
1082 }
1083 skb_deaggr = mwifiex_alloc_dma_align_buf(pkt_len,
1084 GFP_KERNEL | GFP_DMA);
1085 if (!skb_deaggr)
1086 break;
1087 skb_put(skb_deaggr, pkt_len);
1088 memcpy(skb_deaggr->data, data + SDIO_HEADER_OFFSET, pkt_len);
1089 skb_pull(skb_deaggr, INTF_HEADER_LEN);
1090
1091 mwifiex_handle_rx_packet(adapter, skb_deaggr);
1092 data += blk_size;
1093 total_pkt_len -= blk_size;
1094 }
1095}
1096
1097/*
1046 * This function decodes a received packet. 1098 * This function decodes a received packet.
1047 * 1099 *
1048 * Based on the type, the packet is treated as either a data, or 1100 * Based on the type, the packet is treated as either a data, or
@@ -1055,11 +1107,28 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1055 u8 *cmd_buf; 1107 u8 *cmd_buf;
1056 __le16 *curr_ptr = (__le16 *)skb->data; 1108 __le16 *curr_ptr = (__le16 *)skb->data;
1057 u16 pkt_len = le16_to_cpu(*curr_ptr); 1109 u16 pkt_len = le16_to_cpu(*curr_ptr);
1110 struct mwifiex_rxinfo *rx_info;
1058 1111
1059 skb_trim(skb, pkt_len); 1112 if (upld_typ != MWIFIEX_TYPE_AGGR_DATA) {
1060 skb_pull(skb, INTF_HEADER_LEN); 1113 skb_trim(skb, pkt_len);
1114 skb_pull(skb, INTF_HEADER_LEN);
1115 }
1061 1116
1062 switch (upld_typ) { 1117 switch (upld_typ) {
1118 case MWIFIEX_TYPE_AGGR_DATA:
1119 dev_dbg(adapter->dev, "info: --- Rx: Aggr Data packet ---\n");
1120 rx_info = MWIFIEX_SKB_RXCB(skb);
1121 rx_info->buf_type = MWIFIEX_TYPE_AGGR_DATA;
1122 if (adapter->rx_work_enabled) {
1123 skb_queue_tail(&adapter->rx_data_q, skb);
1124 atomic_inc(&adapter->rx_pending);
1125 adapter->data_received = true;
1126 } else {
1127 mwifiex_deaggr_sdio_pkt(adapter, skb);
1128 dev_kfree_skb_any(skb);
1129 }
1130 break;
1131
1063 case MWIFIEX_TYPE_DATA: 1132 case MWIFIEX_TYPE_DATA:
1064 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n"); 1133 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
1065 if (adapter->rx_work_enabled) { 1134 if (adapter->rx_work_enabled) {
@@ -1127,17 +1196,17 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1127 * provided there is space left, processed and finally uploaded. 1196 * provided there is space left, processed and finally uploaded.
1128 */ 1197 */
1129static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, 1198static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1130 struct sk_buff *skb, u8 port) 1199 u16 rx_len, u8 port)
1131{ 1200{
1132 struct sdio_mmc_card *card = adapter->card; 1201 struct sdio_mmc_card *card = adapter->card;
1133 s32 f_do_rx_aggr = 0; 1202 s32 f_do_rx_aggr = 0;
1134 s32 f_do_rx_cur = 0; 1203 s32 f_do_rx_cur = 0;
1135 s32 f_aggr_cur = 0; 1204 s32 f_aggr_cur = 0;
1205 s32 f_post_aggr_cur = 0;
1136 struct sk_buff *skb_deaggr; 1206 struct sk_buff *skb_deaggr;
1137 u32 pind; 1207 struct sk_buff *skb = NULL;
1138 u32 pkt_len, pkt_type, mport; 1208 u32 pkt_len, pkt_type, mport, pind;
1139 u8 *curr_ptr; 1209 u8 *curr_ptr;
1140 u32 rx_len = skb->len;
1141 1210
1142 if ((card->has_control_mask) && (port == CTRL_PORT)) { 1211 if ((card->has_control_mask) && (port == CTRL_PORT)) {
1143 /* Read the command Resp without aggr */ 1212 /* Read the command Resp without aggr */
@@ -1164,12 +1233,12 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1164 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); 1233 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
1165 1234
1166 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1235 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1167 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) { 1236 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len)) {
1168 f_aggr_cur = 1; 1237 f_aggr_cur = 1;
1169 } else { 1238 } else {
1170 /* No room in Aggr buf, do rx aggr now */ 1239 /* No room in Aggr buf, do rx aggr now */
1171 f_do_rx_aggr = 1; 1240 f_do_rx_aggr = 1;
1172 f_do_rx_cur = 1; 1241 f_post_aggr_cur = 1;
1173 } 1242 }
1174 } else { 1243 } else {
1175 /* Rx aggr not in progress */ 1244 /* Rx aggr not in progress */
@@ -1182,7 +1251,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1182 1251
1183 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1252 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1184 f_do_rx_aggr = 1; 1253 f_do_rx_aggr = 1;
1185 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) 1254 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len))
1186 f_aggr_cur = 1; 1255 f_aggr_cur = 1;
1187 else 1256 else
1188 /* No room in Aggr buf, do rx aggr now */ 1257 /* No room in Aggr buf, do rx aggr now */
@@ -1195,7 +1264,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1195 if (f_aggr_cur) { 1264 if (f_aggr_cur) {
1196 dev_dbg(adapter->dev, "info: current packet aggregation\n"); 1265 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1197 /* Curr pkt can be aggregated */ 1266 /* Curr pkt can be aggregated */
1198 mp_rx_aggr_setup(card, skb, port); 1267 mp_rx_aggr_setup(card, rx_len, port);
1199 1268
1200 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || 1269 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
1201 mp_rx_aggr_port_limit_reached(card)) { 1270 mp_rx_aggr_port_limit_reached(card)) {
@@ -1238,16 +1307,29 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1238 curr_ptr = card->mpa_rx.buf; 1307 curr_ptr = card->mpa_rx.buf;
1239 1308
1240 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) { 1309 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1310 u32 *len_arr = card->mpa_rx.len_arr;
1241 1311
1242 /* get curr PKT len & type */ 1312 /* get curr PKT len & type */
1243 pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]); 1313 pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]);
1244 pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]); 1314 pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]);
1245 1315
1246 /* copy pkt to deaggr buf */ 1316 /* copy pkt to deaggr buf */
1247 skb_deaggr = card->mpa_rx.skb_arr[pind]; 1317 skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],
1318 GFP_KERNEL |
1319 GFP_DMA);
1320 if (!skb_deaggr) {
1321 dev_err(adapter->dev, "skb allocation failure drop pkt len=%d type=%d\n",
1322 pkt_len, pkt_type);
1323 curr_ptr += len_arr[pind];
1324 continue;
1325 }
1248 1326
1249 if ((pkt_type == MWIFIEX_TYPE_DATA) && (pkt_len <= 1327 skb_put(skb_deaggr, len_arr[pind]);
1250 card->mpa_rx.len_arr[pind])) { 1328
1329 if ((pkt_type == MWIFIEX_TYPE_DATA ||
1330 (pkt_type == MWIFIEX_TYPE_AGGR_DATA &&
1331 adapter->sdio_rx_aggr_enable)) &&
1332 (pkt_len <= len_arr[pind])) {
1251 1333
1252 memcpy(skb_deaggr->data, curr_ptr, pkt_len); 1334 memcpy(skb_deaggr->data, curr_ptr, pkt_len);
1253 1335
@@ -1257,13 +1339,15 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1257 mwifiex_decode_rx_packet(adapter, skb_deaggr, 1339 mwifiex_decode_rx_packet(adapter, skb_deaggr,
1258 pkt_type); 1340 pkt_type);
1259 } else { 1341 } else {
1260 dev_err(adapter->dev, "wrong aggr pkt:" 1342 dev_err(adapter->dev, " drop wrong aggr pkt:\t"
1261 " type=%d len=%d max_len=%d\n", 1343 "sdio_single_port_rx_aggr=%d\t"
1344 "type=%d len=%d max_len=%d\n",
1345 adapter->sdio_rx_aggr_enable,
1262 pkt_type, pkt_len, 1346 pkt_type, pkt_len,
1263 card->mpa_rx.len_arr[pind]); 1347 len_arr[pind]);
1264 dev_kfree_skb_any(skb_deaggr); 1348 dev_kfree_skb_any(skb_deaggr);
1265 } 1349 }
1266 curr_ptr += card->mpa_rx.len_arr[pind]; 1350 curr_ptr += len_arr[pind];
1267 } 1351 }
1268 MP_RX_AGGR_BUF_RESET(card); 1352 MP_RX_AGGR_BUF_RESET(card);
1269 } 1353 }
@@ -1273,28 +1357,46 @@ rx_curr_single:
1273 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n", 1357 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
1274 port, rx_len); 1358 port, rx_len);
1275 1359
1360 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1361 if (!skb) {
1362 dev_err(adapter->dev, "single skb allocated fail,\t"
1363 "drop pkt port=%d len=%d\n", port, rx_len);
1364 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1365 card->mpa_rx.buf, rx_len,
1366 adapter->ioport + port))
1367 goto error;
1368 return 0;
1369 }
1370
1371 skb_put(skb, rx_len);
1372
1276 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, 1373 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1277 skb->data, skb->len, 1374 skb->data, skb->len,
1278 adapter->ioport + port)) 1375 adapter->ioport + port))
1279 goto error; 1376 goto error;
1377 if (!adapter->sdio_rx_aggr_enable &&
1378 pkt_type == MWIFIEX_TYPE_AGGR_DATA) {
1379 dev_err(adapter->dev, "drop wrong pkt type %d\t"
1380 "current SDIO RX Aggr not enabled\n",
1381 pkt_type);
1382 dev_kfree_skb_any(skb);
1383 return 0;
1384 }
1280 1385
1281 mwifiex_decode_rx_packet(adapter, skb, pkt_type); 1386 mwifiex_decode_rx_packet(adapter, skb, pkt_type);
1282 } 1387 }
1388 if (f_post_aggr_cur) {
1389 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1390 /* Curr pkt can be aggregated */
1391 mp_rx_aggr_setup(card, rx_len, port);
1392 }
1283 1393
1284 return 0; 1394 return 0;
1285
1286error: 1395error:
1287 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1396 if (MP_RX_AGGR_IN_PROGRESS(card))
1288 /* Multiport-aggregation transfer failed - cleanup */
1289 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1290 /* copy pkt to deaggr buf */
1291 skb_deaggr = card->mpa_rx.skb_arr[pind];
1292 dev_kfree_skb_any(skb_deaggr);
1293 }
1294 MP_RX_AGGR_BUF_RESET(card); 1397 MP_RX_AGGR_BUF_RESET(card);
1295 }
1296 1398
1297 if (f_do_rx_cur) 1399 if (f_do_rx_cur && skb)
1298 /* Single transfer pending. Free curr buff also */ 1400 /* Single transfer pending. Free curr buff also */
1299 dev_kfree_skb_any(skb); 1401 dev_kfree_skb_any(skb);
1300 1402
@@ -1356,8 +1458,9 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1356 MWIFIEX_RX_DATA_BUF_SIZE) 1458 MWIFIEX_RX_DATA_BUF_SIZE)
1357 return -1; 1459 return -1;
1358 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1460 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1461 dev_dbg(adapter->dev, "info: rx_len = %d\n", rx_len);
1359 1462
1360 skb = mwifiex_alloc_rx_buf(rx_len, GFP_KERNEL | GFP_DMA); 1463 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1361 if (!skb) 1464 if (!skb)
1362 return -1; 1465 return -1;
1363 1466
@@ -1447,28 +1550,16 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1447 1) / MWIFIEX_SDIO_BLOCK_SIZE; 1550 1) / MWIFIEX_SDIO_BLOCK_SIZE;
1448 if (rx_len <= INTF_HEADER_LEN || 1551 if (rx_len <= INTF_HEADER_LEN ||
1449 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > 1552 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
1450 MWIFIEX_RX_DATA_BUF_SIZE) { 1553 card->mpa_rx.buf_size) {
1451 dev_err(adapter->dev, "invalid rx_len=%d\n", 1554 dev_err(adapter->dev, "invalid rx_len=%d\n",
1452 rx_len); 1555 rx_len);
1453 return -1; 1556 return -1;
1454 } 1557 }
1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1456
1457 skb = mwifiex_alloc_rx_buf(rx_len,
1458 GFP_KERNEL | GFP_DMA);
1459
1460 if (!skb) {
1461 dev_err(adapter->dev, "%s: failed to alloc skb",
1462 __func__);
1463 return -1;
1464 }
1465 1558
1466 skb_put(skb, rx_len); 1559 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1467 1560 dev_dbg(adapter->dev, "info: rx_len = %d\n", rx_len);
1468 dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
1469 rx_len, skb->len);
1470 1561
1471 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, 1562 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, rx_len,
1472 port)) { 1563 port)) {
1473 dev_err(adapter->dev, "card_to_host_mpa failed:" 1564 dev_err(adapter->dev, "card_to_host_mpa failed:"
1474 " int status=%#x\n", sdio_ireg); 1565 " int status=%#x\n", sdio_ireg);
@@ -1736,6 +1827,7 @@ static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
1736 u32 mpa_tx_buf_size, u32 mpa_rx_buf_size) 1827 u32 mpa_tx_buf_size, u32 mpa_rx_buf_size)
1737{ 1828{
1738 struct sdio_mmc_card *card = adapter->card; 1829 struct sdio_mmc_card *card = adapter->card;
1830 u32 rx_buf_size;
1739 int ret = 0; 1831 int ret = 0;
1740 1832
1741 card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL); 1833 card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL);
@@ -1746,13 +1838,15 @@ static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
1746 1838
1747 card->mpa_tx.buf_size = mpa_tx_buf_size; 1839 card->mpa_tx.buf_size = mpa_tx_buf_size;
1748 1840
1749 card->mpa_rx.buf = kzalloc(mpa_rx_buf_size, GFP_KERNEL); 1841 rx_buf_size = max_t(u32, mpa_rx_buf_size,
1842 (u32)SDIO_MAX_AGGR_BUF_SIZE);
1843 card->mpa_rx.buf = kzalloc(rx_buf_size, GFP_KERNEL);
1750 if (!card->mpa_rx.buf) { 1844 if (!card->mpa_rx.buf) {
1751 ret = -1; 1845 ret = -1;
1752 goto error; 1846 goto error;
1753 } 1847 }
1754 1848
1755 card->mpa_rx.buf_size = mpa_rx_buf_size; 1849 card->mpa_rx.buf_size = rx_buf_size;
1756 1850
1757error: 1851error:
1758 if (ret) { 1852 if (ret) {
@@ -1951,6 +2045,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1951 port, card->mp_data_port_mask); 2045 port, card->mp_data_port_mask);
1952} 2046}
1953 2047
2048static struct mwifiex_adapter *save_adapter;
1954static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) 2049static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
1955{ 2050{
1956 struct sdio_mmc_card *card = adapter->card; 2051 struct sdio_mmc_card *card = adapter->card;
@@ -2019,10 +2114,8 @@ rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,
2019} 2114}
2020 2115
2021/* This function dump firmware memory to file */ 2116/* This function dump firmware memory to file */
2022static void mwifiex_sdio_fw_dump_work(struct work_struct *work) 2117static void mwifiex_sdio_fw_dump_work(struct mwifiex_adapter *adapter)
2023{ 2118{
2024 struct mwifiex_adapter *adapter =
2025 container_of(work, struct mwifiex_adapter, iface_work);
2026 struct sdio_mmc_card *card = adapter->card; 2119 struct sdio_mmc_card *card = adapter->card;
2027 int ret = 0; 2120 int ret = 0;
2028 unsigned int reg, reg_start, reg_end; 2121 unsigned int reg, reg_start, reg_end;
@@ -2144,36 +2237,36 @@ done:
2144 2237
2145static void mwifiex_sdio_work(struct work_struct *work) 2238static void mwifiex_sdio_work(struct work_struct *work)
2146{ 2239{
2147 struct mwifiex_adapter *adapter =
2148 container_of(work, struct mwifiex_adapter, iface_work);
2149
2150 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2151 &adapter->iface_work_flags))
2152 mwifiex_sdio_card_reset_work(adapter);
2153 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP, 2240 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2154 &adapter->iface_work_flags)) 2241 &iface_work_flags))
2155 mwifiex_sdio_fw_dump_work(work); 2242 mwifiex_sdio_fw_dump_work(save_adapter);
2243 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2244 &iface_work_flags))
2245 mwifiex_sdio_card_reset_work(save_adapter);
2156} 2246}
2157 2247
2248static DECLARE_WORK(sdio_work, mwifiex_sdio_work);
2158/* This function resets the card */ 2249/* This function resets the card */
2159static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) 2250static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
2160{ 2251{
2161 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags)) 2252 save_adapter = adapter;
2253 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags))
2162 return; 2254 return;
2163 2255
2164 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags); 2256 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
2165 2257
2166 schedule_work(&adapter->iface_work); 2258 schedule_work(&sdio_work);
2167} 2259}
2168 2260
2169/* This function dumps FW information */ 2261/* This function dumps FW information */
2170static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter) 2262static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2171{ 2263{
2172 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags)) 2264 save_adapter = adapter;
2265 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
2173 return; 2266 return;
2174 2267
2175 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags); 2268 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
2176 schedule_work(&adapter->iface_work); 2269 schedule_work(&sdio_work);
2177} 2270}
2178 2271
2179/* Function to dump SDIO function registers and SDIO scratch registers in case 2272/* Function to dump SDIO function registers and SDIO scratch registers in case
@@ -2289,9 +2382,9 @@ static struct mwifiex_if_ops sdio_ops = {
2289 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, 2382 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
2290 .event_complete = mwifiex_sdio_event_complete, 2383 .event_complete = mwifiex_sdio_event_complete,
2291 .card_reset = mwifiex_sdio_card_reset, 2384 .card_reset = mwifiex_sdio_card_reset,
2292 .iface_work = mwifiex_sdio_work,
2293 .fw_dump = mwifiex_sdio_fw_dump, 2385 .fw_dump = mwifiex_sdio_fw_dump,
2294 .reg_dump = mwifiex_sdio_reg_dump, 2386 .reg_dump = mwifiex_sdio_reg_dump,
2387 .deaggr_pkt = mwifiex_deaggr_sdio_pkt,
2295}; 2388};
2296 2389
2297/* 2390/*
@@ -2328,6 +2421,7 @@ mwifiex_sdio_cleanup_module(void)
2328 2421
2329 /* Set the flag as user is removing this module. */ 2422 /* Set the flag as user is removing this module. */
2330 user_rmmod = 1; 2423 user_rmmod = 1;
2424 cancel_work_sync(&sdio_work);
2331 2425
2332 sdio_unregister_driver(&mwifiex_sdio); 2426 sdio_unregister_driver(&mwifiex_sdio);
2333} 2427}
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index c636944c77bc..6f645cf47369 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -67,6 +67,8 @@
67 67
68#define MWIFIEX_MP_AGGR_BUF_SIZE_16K (16384) 68#define MWIFIEX_MP_AGGR_BUF_SIZE_16K (16384)
69#define MWIFIEX_MP_AGGR_BUF_SIZE_32K (32768) 69#define MWIFIEX_MP_AGGR_BUF_SIZE_32K (32768)
70/* we leave one block of 256 bytes for DMA alignment*/
71#define MWIFIEX_MP_AGGR_BUF_SIZE_MAX (65280)
70 72
71/* Misc. Config Register : Auto Re-enable interrupts */ 73/* Misc. Config Register : Auto Re-enable interrupts */
72#define AUTO_RE_ENABLE_INT BIT(4) 74#define AUTO_RE_ENABLE_INT BIT(4)
@@ -458,8 +460,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
458 .max_ports = 32, 460 .max_ports = 32,
459 .mp_agg_pkt_limit = 16, 461 .mp_agg_pkt_limit = 16,
460 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 462 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
461 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 463 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,
462 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 464 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,
463 .supports_sdio_new_mode = true, 465 .supports_sdio_new_mode = true,
464 .has_control_mask = false, 466 .has_control_mask = false,
465 .can_dump_fw = true, 467 .can_dump_fw = true,
@@ -571,9 +573,9 @@ mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
571 573
572/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */ 574/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
573static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card, 575static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
574 struct sk_buff *skb, u8 port) 576 u16 rx_len, u8 port)
575{ 577{
576 card->mpa_rx.buf_len += skb->len; 578 card->mpa_rx.buf_len += rx_len;
577 579
578 if (!card->mpa_rx.pkt_cnt) 580 if (!card->mpa_rx.pkt_cnt)
579 card->mpa_rx.start_port = port; 581 card->mpa_rx.start_port = port;
@@ -586,8 +588,8 @@ static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
586 else 588 else
587 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1); 589 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1);
588 } 590 }
589 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = skb; 591 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = NULL;
590 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = skb->len; 592 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = rx_len;
591 card->mpa_rx.pkt_cnt++; 593 card->mpa_rx.pkt_cnt++;
592} 594}
593#endif /* _MWIFIEX_SDIO_H */ 595#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index f7d204ffd6e9..49422f2a5380 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1370,22 +1370,29 @@ mwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
1370 struct mwifiex_ds_mef_cfg *mef) 1370 struct mwifiex_ds_mef_cfg *mef)
1371{ 1371{
1372 struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg; 1372 struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg;
1373 struct mwifiex_fw_mef_entry *mef_entry = NULL;
1373 u8 *pos = (u8 *)mef_cfg; 1374 u8 *pos = (u8 *)mef_cfg;
1375 u16 i;
1374 1376
1375 cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG); 1377 cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG);
1376 1378
1377 mef_cfg->criteria = cpu_to_le32(mef->criteria); 1379 mef_cfg->criteria = cpu_to_le32(mef->criteria);
1378 mef_cfg->num_entries = cpu_to_le16(mef->num_entries); 1380 mef_cfg->num_entries = cpu_to_le16(mef->num_entries);
1379 pos += sizeof(*mef_cfg); 1381 pos += sizeof(*mef_cfg);
1380 mef_cfg->mef_entry->mode = mef->mef_entry->mode;
1381 mef_cfg->mef_entry->action = mef->mef_entry->action;
1382 pos += sizeof(*(mef_cfg->mef_entry));
1383 1382
1384 if (mwifiex_cmd_append_rpn_expression(priv, mef->mef_entry, &pos)) 1383 for (i = 0; i < mef->num_entries; i++) {
1385 return -1; 1384 mef_entry = (struct mwifiex_fw_mef_entry *)pos;
1385 mef_entry->mode = mef->mef_entry[i].mode;
1386 mef_entry->action = mef->mef_entry[i].action;
1387 pos += sizeof(*mef_cfg->mef_entry);
1388
1389 if (mwifiex_cmd_append_rpn_expression(priv,
1390 &mef->mef_entry[i], &pos))
1391 return -1;
1386 1392
1387 mef_cfg->mef_entry->exprsize = 1393 mef_entry->exprsize =
1388 cpu_to_le16(pos - mef_cfg->mef_entry->expr); 1394 cpu_to_le16(pos - mef_entry->expr);
1395 }
1389 cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN); 1396 cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN);
1390 1397
1391 return 0; 1398 return 0;
@@ -1664,6 +1671,25 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1664 1671
1665 return 0; 1672 return 0;
1666} 1673}
1674
1675/* This function prepares command of sdio rx aggr info. */
1676static int mwifiex_cmd_sdio_rx_aggr_cfg(struct host_cmd_ds_command *cmd,
1677 u16 cmd_action, void *data_buf)
1678{
1679 struct host_cmd_sdio_sp_rx_aggr_cfg *cfg =
1680 &cmd->params.sdio_rx_aggr_cfg;
1681
1682 cmd->command = cpu_to_le16(HostCmd_CMD_SDIO_SP_RX_AGGR_CFG);
1683 cmd->size =
1684 cpu_to_le16(sizeof(struct host_cmd_sdio_sp_rx_aggr_cfg) +
1685 S_DS_GEN);
1686 cfg->action = cmd_action;
1687 if (cmd_action == HostCmd_ACT_GEN_SET)
1688 cfg->enable = *(u8 *)data_buf;
1689
1690 return 0;
1691}
1692
1667/* 1693/*
1668 * This function prepares the commands before sending them to the firmware. 1694 * This function prepares the commands before sending them to the firmware.
1669 * 1695 *
@@ -1901,6 +1927,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1901 ret = mwifiex_cmd_issue_chan_report_request(priv, cmd_ptr, 1927 ret = mwifiex_cmd_issue_chan_report_request(priv, cmd_ptr,
1902 data_buf); 1928 data_buf);
1903 break; 1929 break;
1930 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
1931 ret = mwifiex_cmd_sdio_rx_aggr_cfg(cmd_ptr, cmd_action,
1932 data_buf);
1933 break;
1904 default: 1934 default:
1905 dev_err(priv->adapter->dev, 1935 dev_err(priv->adapter->dev,
1906 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1936 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
@@ -1940,6 +1970,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
1940 struct mwifiex_ds_auto_ds auto_ds; 1970 struct mwifiex_ds_auto_ds auto_ds;
1941 enum state_11d_t state_11d; 1971 enum state_11d_t state_11d;
1942 struct mwifiex_ds_11n_tx_cfg tx_cfg; 1972 struct mwifiex_ds_11n_tx_cfg tx_cfg;
1973 u8 sdio_sp_rx_aggr_enable;
1943 1974
1944 if (first_sta) { 1975 if (first_sta) {
1945 if (priv->adapter->iface_type == MWIFIEX_PCIE) { 1976 if (priv->adapter->iface_type == MWIFIEX_PCIE) {
@@ -1983,6 +2014,22 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
1983 if (ret) 2014 if (ret)
1984 return -1; 2015 return -1;
1985 2016
2017 /** Set SDIO Single Port RX Aggr Info */
2018 if (priv->adapter->iface_type == MWIFIEX_SDIO &&
2019 ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info)) {
2020 sdio_sp_rx_aggr_enable = true;
2021 ret = mwifiex_send_cmd(priv,
2022 HostCmd_CMD_SDIO_SP_RX_AGGR_CFG,
2023 HostCmd_ACT_GEN_SET, 0,
2024 &sdio_sp_rx_aggr_enable,
2025 true);
2026 if (ret) {
2027 dev_err(priv->adapter->dev,
2028 "error while enabling SP aggregation..disable it");
2029 adapter->sdio_rx_aggr_enable = false;
2030 }
2031 }
2032
1986 /* Reconfigure tx buf size */ 2033 /* Reconfigure tx buf size */
1987 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, 2034 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
1988 HostCmd_ACT_GEN_SET, 0, 2035 HostCmd_ACT_GEN_SET, 0,
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 5f8da5924666..88dc6b672ef4 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -90,6 +90,10 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
90 case HostCmd_CMD_MAC_CONTROL: 90 case HostCmd_CMD_MAC_CONTROL:
91 break; 91 break;
92 92
93 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
94 dev_err(priv->adapter->dev, "SDIO RX single-port aggregation Not support\n");
95 break;
96
93 default: 97 default:
94 break; 98 break;
95 } 99 }
@@ -943,6 +947,20 @@ static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
943 return 0; 947 return 0;
944} 948}
945 949
950/** This Function handles the command response of sdio rx aggr */
951static int mwifiex_ret_sdio_rx_aggr_cfg(struct mwifiex_private *priv,
952 struct host_cmd_ds_command *resp)
953{
954 struct mwifiex_adapter *adapter = priv->adapter;
955 struct host_cmd_sdio_sp_rx_aggr_cfg *cfg =
956 &resp->params.sdio_rx_aggr_cfg;
957
958 adapter->sdio_rx_aggr_enable = cfg->enable;
959 adapter->sdio_rx_block_size = le16_to_cpu(cfg->block_size);
960
961 return 0;
962}
963
946/* 964/*
947 * This function handles the command responses. 965 * This function handles the command responses.
948 * 966 *
@@ -1124,6 +1142,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
1124 break; 1142 break;
1125 case HostCmd_CMD_CHAN_REPORT_REQUEST: 1143 case HostCmd_CMD_CHAN_REPORT_REQUEST:
1126 break; 1144 break;
1145 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
1146 ret = mwifiex_ret_sdio_rx_aggr_cfg(priv, resp);
1147 break;
1127 default: 1148 default:
1128 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 1149 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
1129 resp->command); 1150 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 64c4223a1e1e..0dc7a1d3993d 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -312,7 +312,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
312 adapter->ps_state = PS_STATE_AWAKE; 312 adapter->ps_state = PS_STATE_AWAKE;
313 adapter->pm_wakeup_card_req = false; 313 adapter->pm_wakeup_card_req = false;
314 adapter->pm_wakeup_fw_try = false; 314 adapter->pm_wakeup_fw_try = false;
315 del_timer_sync(&adapter->wakeup_timer); 315 del_timer(&adapter->wakeup_timer);
316 break; 316 break;
317 } 317 }
318 if (!mwifiex_send_null_packet 318 if (!mwifiex_send_null_packet
@@ -327,7 +327,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
327 adapter->ps_state = PS_STATE_AWAKE; 327 adapter->ps_state = PS_STATE_AWAKE;
328 adapter->pm_wakeup_card_req = false; 328 adapter->pm_wakeup_card_req = false;
329 adapter->pm_wakeup_fw_try = false; 329 adapter->pm_wakeup_fw_try = false;
330 del_timer_sync(&adapter->wakeup_timer); 330 del_timer(&adapter->wakeup_timer);
331 331
332 break; 332 break;
333 333
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index ea4549f0e0b9..a245f444aeec 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -92,6 +92,12 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
92 else 92 else
93 head_ptr = mwifiex_process_sta_txpd(priv, skb); 93 head_ptr = mwifiex_process_sta_txpd(priv, skb);
94 94
95 if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
96 skb_queue_tail(&adapter->tx_data_q, skb);
97 atomic_inc(&adapter->tx_queued);
98 return 0;
99 }
100
95 if (head_ptr) { 101 if (head_ptr) {
96 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) 102 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
97 local_tx_pd = (struct txpd *)(head_ptr + hroom); 103 local_tx_pd = (struct txpd *)(head_ptr + hroom);
@@ -142,6 +148,123 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
142 return ret; 148 return ret;
143} 149}
144 150
151static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
152 struct sk_buff *skb,
153 struct mwifiex_tx_param *tx_param)
154{
155 struct txpd *local_tx_pd = NULL;
156 u8 *head_ptr = skb->data;
157 int ret = 0;
158 struct mwifiex_private *priv;
159 struct mwifiex_txinfo *tx_info;
160
161 tx_info = MWIFIEX_SKB_TXCB(skb);
162 priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
163 tx_info->bss_type);
164 if (!priv) {
165 dev_err(adapter->dev, "data: priv not found. Drop TX packet\n");
166 adapter->dbg.num_tx_host_to_card_failure++;
167 mwifiex_write_data_complete(adapter, skb, 0, 0);
168 return ret;
169 }
170 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
171 if (adapter->iface_type == MWIFIEX_USB)
172 local_tx_pd = (struct txpd *)head_ptr;
173 else
174 local_tx_pd = (struct txpd *) (head_ptr +
175 INTF_HEADER_LEN);
176 }
177
178 if (adapter->iface_type == MWIFIEX_USB) {
179 adapter->data_sent = true;
180 ret = adapter->if_ops.host_to_card(adapter,
181 MWIFIEX_USB_EP_DATA,
182 skb, NULL);
183 } else {
184 ret = adapter->if_ops.host_to_card(adapter,
185 MWIFIEX_TYPE_DATA,
186 skb, tx_param);
187 }
188 switch (ret) {
189 case -ENOSR:
190 dev_err(adapter->dev, "data: -ENOSR is returned\n");
191 break;
192 case -EBUSY:
193 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
194 (adapter->pps_uapsd_mode) &&
195 (adapter->tx_lock_flag)) {
196 priv->adapter->tx_lock_flag = false;
197 if (local_tx_pd)
198 local_tx_pd->flags = 0;
199 }
200 skb_queue_head(&adapter->tx_data_q, skb);
201 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
202 atomic_add(tx_info->aggr_num, &adapter->tx_queued);
203 else
204 atomic_inc(&adapter->tx_queued);
205 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
206 break;
207 case -1:
208 if (adapter->iface_type != MWIFIEX_PCIE)
209 adapter->data_sent = false;
210 dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
211 ret);
212 adapter->dbg.num_tx_host_to_card_failure++;
213 mwifiex_write_data_complete(adapter, skb, 0, ret);
214 break;
215 case -EINPROGRESS:
216 if (adapter->iface_type != MWIFIEX_PCIE)
217 adapter->data_sent = false;
218 break;
219 case 0:
220 mwifiex_write_data_complete(adapter, skb, 0, ret);
221 break;
222 default:
223 break;
224 }
225 return ret;
226}
227
228static int
229mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter)
230{
231 struct sk_buff *skb, *skb_next;
232 struct mwifiex_txinfo *tx_info;
233 struct mwifiex_tx_param tx_param;
234
235 skb = skb_dequeue(&adapter->tx_data_q);
236 if (!skb)
237 return -1;
238
239 tx_info = MWIFIEX_SKB_TXCB(skb);
240 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
241 atomic_sub(tx_info->aggr_num, &adapter->tx_queued);
242 else
243 atomic_dec(&adapter->tx_queued);
244
245 if (!skb_queue_empty(&adapter->tx_data_q))
246 skb_next = skb_peek(&adapter->tx_data_q);
247 else
248 skb_next = NULL;
249 tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0);
250 if (!tx_param.next_pkt_len) {
251 if (!mwifiex_wmm_lists_empty(adapter))
252 tx_param.next_pkt_len = 1;
253 }
254 return mwifiex_host_to_card(adapter, skb, &tx_param);
255}
256
257void
258mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
259{
260 do {
261 if (adapter->data_sent || adapter->tx_lock_flag)
262 break;
263 if (mwifiex_dequeue_tx_queue(adapter))
264 break;
265 } while (!skb_queue_empty(&adapter->tx_data_q));
266}
267
145/* 268/*
146 * Packet send completion callback handler. 269 * Packet send completion callback handler.
147 * 270 *
@@ -179,8 +302,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
179 priv->stats.tx_errors++; 302 priv->stats.tx_errors++;
180 } 303 }
181 304
182 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) 305 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
183 atomic_dec_return(&adapter->pending_bridged_pkts); 306 atomic_dec_return(&adapter->pending_bridged_pkts);
307 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
308 goto done;
309 }
184 310
185 if (aggr) 311 if (aggr)
186 /* For skb_aggr, do not wake up tx queue */ 312 /* For skb_aggr, do not wake up tx queue */
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 223873022ffe..fd8027f200a0 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -193,7 +193,7 @@ static void mwifiex_usb_rx_complete(struct urb *urb)
193 dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n", 193 dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n",
194 recv_length, status); 194 recv_length, status);
195 if (status == -EINPROGRESS) { 195 if (status == -EINPROGRESS) {
196 queue_work(adapter->workqueue, &adapter->main_work); 196 mwifiex_queue_main_work(adapter);
197 197
198 /* urb for data_ep is re-submitted now; 198 /* urb for data_ep is re-submitted now;
199 * urb for cmd_ep will be re-submitted in callback 199 * urb for cmd_ep will be re-submitted in callback
@@ -262,7 +262,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
262 urb->status ? -1 : 0); 262 urb->status ? -1 : 0);
263 } 263 }
264 264
265 queue_work(adapter->workqueue, &adapter->main_work); 265 mwifiex_queue_main_work(adapter);
266 266
267 return; 267 return;
268} 268}
@@ -1006,7 +1006,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
1006{ 1006{
1007 /* Simulation of HS_AWAKE event */ 1007 /* Simulation of HS_AWAKE event */
1008 adapter->pm_wakeup_fw_try = false; 1008 adapter->pm_wakeup_fw_try = false;
1009 del_timer_sync(&adapter->wakeup_timer); 1009 del_timer(&adapter->wakeup_timer);
1010 adapter->pm_wakeup_card_req = false; 1010 adapter->pm_wakeup_card_req = false;
1011 adapter->ps_state = PS_STATE_AWAKE; 1011 adapter->ps_state = PS_STATE_AWAKE;
1012 1012
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 2148a573396b..b8a45872354d 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -632,7 +632,7 @@ void mwifiex_hist_data_reset(struct mwifiex_private *priv)
632 atomic_set(&phist_data->sig_str[ix], 0); 632 atomic_set(&phist_data->sig_str[ix], 0);
633} 633}
634 634
635void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags) 635void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags)
636{ 636{
637 struct sk_buff *skb; 637 struct sk_buff *skb;
638 int buf_len, pad; 638 int buf_len, pad;
@@ -653,4 +653,4 @@ void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags)
653 653
654 return skb; 654 return skb;
655} 655}
656EXPORT_SYMBOL_GPL(mwifiex_alloc_rx_buf); 656EXPORT_SYMBOL_GPL(mwifiex_alloc_dma_align_buf);
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 0cd4f6bed9fc..b2e99569a0f8 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -157,6 +157,8 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra)
157 157
158 ra_list->is_11n_enabled = 0; 158 ra_list->is_11n_enabled = 0;
159 ra_list->tdls_link = false; 159 ra_list->tdls_link = false;
160 ra_list->ba_status = BA_SETUP_NONE;
161 ra_list->amsdu_in_ampdu = false;
160 if (!mwifiex_queuing_ra_based(priv)) { 162 if (!mwifiex_queuing_ra_based(priv)) {
161 if (mwifiex_get_tdls_link_status(priv, ra) == 163 if (mwifiex_get_tdls_link_status(priv, ra) ==
162 TDLS_SETUP_COMPLETE) { 164 TDLS_SETUP_COMPLETE) {
@@ -574,7 +576,7 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
574 * This function retrieves a particular RA list node, matching with the 576 * This function retrieves a particular RA list node, matching with the
575 * given TID and RA address. 577 * given TID and RA address.
576 */ 578 */
577static struct mwifiex_ra_list_tbl * 579struct mwifiex_ra_list_tbl *
578mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, 580mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
579 const u8 *ra_addr) 581 const u8 *ra_addr)
580{ 582{
@@ -942,14 +944,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
942 struct mwifiex_ra_list_tbl *ptr; 944 struct mwifiex_ra_list_tbl *ptr;
943 struct mwifiex_tid_tbl *tid_ptr; 945 struct mwifiex_tid_tbl *tid_ptr;
944 atomic_t *hqp; 946 atomic_t *hqp;
945 unsigned long flags_bss, flags_ra; 947 unsigned long flags_ra;
946 int i, j; 948 int i, j;
947 949
948 /* check the BSS with highest priority first */ 950 /* check the BSS with highest priority first */
949 for (j = adapter->priv_num - 1; j >= 0; --j) { 951 for (j = adapter->priv_num - 1; j >= 0; --j) {
950 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
951 flags_bss);
952
953 /* iterate over BSS with the equal priority */ 952 /* iterate over BSS with the equal priority */
954 list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur, 953 list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur,
955 &adapter->bss_prio_tbl[j].bss_prio_head, 954 &adapter->bss_prio_tbl[j].bss_prio_head,
@@ -985,19 +984,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
985 } 984 }
986 } 985 }
987 986
988 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
989 flags_bss);
990 } 987 }
991 988
992 return NULL; 989 return NULL;
993 990
994found: 991found:
995 /* holds bss_prio_lock / ra_list_spinlock */ 992 /* holds ra_list_spinlock */
996 if (atomic_read(hqp) > i) 993 if (atomic_read(hqp) > i)
997 atomic_set(hqp, i); 994 atomic_set(hqp, i);
998 spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags_ra); 995 spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags_ra);
999 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
1000 flags_bss);
1001 996
1002 *priv = priv_tmp; 997 *priv = priv_tmp;
1003 *tid = tos_to_tid[i]; 998 *tid = tos_to_tid[i];
@@ -1179,6 +1174,14 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1179 1174
1180 skb = skb_dequeue(&ptr->skb_head); 1175 skb = skb_dequeue(&ptr->skb_head);
1181 1176
1177 if (adapter->data_sent || adapter->tx_lock_flag) {
1178 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1179 ra_list_flags);
1180 skb_queue_tail(&adapter->tx_data_q, skb);
1181 atomic_inc(&adapter->tx_queued);
1182 return;
1183 }
1184
1182 if (!skb_queue_empty(&ptr->skb_head)) 1185 if (!skb_queue_empty(&ptr->skb_head))
1183 skb_next = skb_peek(&ptr->skb_head); 1186 skb_next = skb_peek(&ptr->skb_head);
1184 else 1187 else
@@ -1276,13 +1279,13 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1276 } 1279 }
1277 1280
1278 if (!ptr->is_11n_enabled || 1281 if (!ptr->is_11n_enabled ||
1279 mwifiex_is_ba_stream_setup(priv, ptr, tid) || 1282 ptr->ba_status ||
1280 priv->wps.session_enable) { 1283 priv->wps.session_enable) {
1281 if (ptr->is_11n_enabled && 1284 if (ptr->is_11n_enabled &&
1282 mwifiex_is_ba_stream_setup(priv, ptr, tid) && 1285 ptr->ba_status &&
1283 mwifiex_is_amsdu_in_ampdu_allowed(priv, ptr, tid) && 1286 ptr->amsdu_in_ampdu &&
1284 mwifiex_is_amsdu_allowed(priv, tid) && 1287 mwifiex_is_amsdu_allowed(priv, tid) &&
1285 mwifiex_is_11n_aggragation_possible(priv, ptr, 1288 mwifiex_is_11n_aggragation_possible(priv, ptr,
1286 adapter->tx_buf_size)) 1289 adapter->tx_buf_size))
1287 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); 1290 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);
1288 /* ra_list_spinlock has been freed in 1291 /* ra_list_spinlock has been freed in
@@ -1329,11 +1332,16 @@ void
1329mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) 1332mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
1330{ 1333{
1331 do { 1334 do {
1332 /* Check if busy */
1333 if (adapter->data_sent || adapter->tx_lock_flag)
1334 break;
1335
1336 if (mwifiex_dequeue_tx_packet(adapter)) 1335 if (mwifiex_dequeue_tx_packet(adapter))
1337 break; 1336 break;
1337 if (adapter->iface_type != MWIFIEX_SDIO) {
1338 if (adapter->data_sent ||
1339 adapter->tx_lock_flag)
1340 break;
1341 } else {
1342 if (atomic_read(&adapter->tx_queued) >=
1343 MWIFIEX_MAX_PKTS_TXQ)
1344 break;
1345 }
1338 } while (!mwifiex_wmm_lists_empty(adapter)); 1346 } while (!mwifiex_wmm_lists_empty(adapter));
1339} 1347}
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 569bd73f33c5..48ece0b35591 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -127,4 +127,6 @@ mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid,
127 const u8 *ra_addr); 127 const u8 *ra_addr);
128u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid); 128u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid);
129 129
130struct mwifiex_ra_list_tbl *mwifiex_wmm_get_ralist_node(struct mwifiex_private
131 *priv, u8 tid, const u8 *ra_addr);
130#endif /* !_MWIFIEX_WMM_H_ */ 132#endif /* !_MWIFIEX_WMM_H_ */