aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2014-11-25 09:43:06 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-11-25 14:09:57 -0500
commit18ca43823f3ce111c6efb8cc90d9f35246527727 (patch)
tree741acf94d777ef84b60adcbf5f533172fec64fc5
parent808bbebcc8fcbcb2b93aefd8b181a0fdccb407c6 (diff)
mwifiex: add Tx status support for ACTION frames
ACK status (0/1) for ACTION frames is informed to cfg80211. We will extend existing logic used for EAPOL frames. The cfg80211 API is different here. Also, we need to explicitly free cloned skb. Signed-off-by: Cathy Luo <cluo@marvell.com> Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c13
-rw-r--r--drivers/net/wireless/mwifiex/decl.h2
-rw-r--r--drivers/net/wireless/mwifiex/main.c10
-rw-r--r--drivers/net/wireless/mwifiex/main.h4
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c3
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c17
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c3
7 files changed, 41 insertions, 11 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 68d5874adc94..f881044e450d 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -194,10 +194,17 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
194 tx_info->pkt_len = pkt_len; 194 tx_info->pkt_len = pkt_len;
195 195
196 mwifiex_form_mgmt_frame(skb, buf, len); 196 mwifiex_form_mgmt_frame(skb, buf, len);
197 mwifiex_queue_tx_pkt(priv, skb);
198
199 *cookie = prandom_u32() | 1; 197 *cookie = prandom_u32() | 1;
200 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC); 198
199 if (ieee80211_is_action(mgmt->frame_control))
200 skb = mwifiex_clone_skb_for_tx_status(priv,
201 skb,
202 MWIFIEX_BUF_FLAG_ACTION_TX_STATUS, cookie);
203 else
204 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
205 GFP_ATOMIC);
206
207 mwifiex_queue_tx_pkt(priv, skb);
201 208
202 wiphy_dbg(wiphy, "info: management frame transmitted\n"); 209 wiphy_dbg(wiphy, "info: management frame transmitted\n");
203 return 0; 210 return 0;
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 9daa88a61377..2269acf41ad8 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -77,6 +77,7 @@
77#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) 77#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
78#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2) 78#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
79#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3) 79#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
80#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4)
80 81
81#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 82#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
82#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 83#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
@@ -161,6 +162,7 @@ struct mwifiex_txinfo {
161 u8 bss_type; 162 u8 bss_type;
162 u32 pkt_len; 163 u32 pkt_len;
163 u8 ack_frame_id; 164 u8 ack_frame_id;
165 u64 cookie;
164}; 166};
165 167
166enum mwifiex_wmm_ac_e { 168enum mwifiex_wmm_ac_e {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index cf31d36a9fdd..d4d2223d1f31 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -608,9 +608,9 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
608 return 0; 608 return 0;
609} 609}
610 610
611static struct sk_buff * 611struct sk_buff *
612mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, 612mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
613 struct sk_buff *skb, u8 flag) 613 struct sk_buff *skb, u8 flag, u64 *cookie)
614{ 614{
615 struct sk_buff *orig_skb = skb; 615 struct sk_buff *orig_skb = skb;
616 struct mwifiex_txinfo *tx_info, *orig_tx_info; 616 struct mwifiex_txinfo *tx_info, *orig_tx_info;
@@ -632,6 +632,10 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
632 orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb); 632 orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb);
633 orig_tx_info->ack_frame_id = id; 633 orig_tx_info->ack_frame_id = id;
634 orig_tx_info->flags |= flag; 634 orig_tx_info->flags |= flag;
635
636 if (flag == MWIFIEX_BUF_FLAG_ACTION_TX_STATUS && cookie)
637 orig_tx_info->cookie = *cookie;
638
635 } else if (skb_shared(skb)) { 639 } else if (skb_shared(skb)) {
636 kfree_skb(orig_skb); 640 kfree_skb(orig_skb);
637 } else { 641 } else {
@@ -703,7 +707,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
703 priv->adapter->fw_api_ver == MWIFIEX_FW_V15)) 707 priv->adapter->fw_api_ver == MWIFIEX_FW_V15))
704 skb = mwifiex_clone_skb_for_tx_status(priv, 708 skb = mwifiex_clone_skb_for_tx_status(priv,
705 skb, 709 skb,
706 MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS); 710 MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS, NULL);
707 711
708 /* Record the current time the packet was queued; used to 712 /* Record the current time the packet was queued; used to
709 * determine the amount of time the packet was queued in 713 * determine the amount of time the packet was queued in
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e19fc2f87436..bdba37b7015d 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1342,6 +1342,10 @@ void mwifiex_clean_auto_tdls(struct mwifiex_private *priv);
1342void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, 1342void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
1343 void *event_body); 1343 void *event_body);
1344 1344
1345struct sk_buff *
1346mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
1347 struct sk_buff *skb, u8 flag, u64 *cookie);
1348
1345#ifdef CONFIG_DEBUG_FS 1349#ifdef CONFIG_DEBUG_FS
1346void mwifiex_debugfs_init(void); 1350void mwifiex_debugfs_init(void);
1347void mwifiex_debugfs_remove(void); 1351void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index c69ecbc1d63f..b896d7375b52 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -77,7 +77,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
77 local_tx_pd->pkt_delay_2ms = 77 local_tx_pd->pkt_delay_2ms =
78 mwifiex_wmm_compute_drv_pkt_delay(priv, skb); 78 mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
79 79
80 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { 80 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
81 tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
81 local_tx_pd->tx_token_id = tx_info->ack_frame_id; 82 local_tx_pd->tx_token_id = tx_info->ack_frame_id;
82 local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS; 83 local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
83 } 84 }
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 782bfd61c300..6ae133333363 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -209,6 +209,7 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
209 struct tx_status_event *tx_status = (void *)priv->adapter->event_body; 209 struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
210 struct sk_buff *ack_skb; 210 struct sk_buff *ack_skb;
211 unsigned long flags; 211 unsigned long flags;
212 struct mwifiex_txinfo *tx_info;
212 213
213 if (!tx_status->tx_token_id) 214 if (!tx_status->tx_token_id)
214 return; 215 return;
@@ -219,7 +220,17 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
219 idr_remove(&priv->ack_status_frames, tx_status->tx_token_id); 220 idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
220 spin_unlock_irqrestore(&priv->ack_status_lock, flags); 221 spin_unlock_irqrestore(&priv->ack_status_lock, flags);
221 222
222 /* consumes ack_skb */ 223 if (ack_skb) {
223 if (ack_skb) 224 tx_info = MWIFIEX_SKB_TXCB(ack_skb);
224 skb_complete_wifi_ack(ack_skb, !tx_status->status); 225
226 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
227 /* consumes ack_skb */
228 skb_complete_wifi_ack(ack_skb, !tx_status->status);
229 } else {
230 cfg80211_mgmt_tx_status(priv->wdev, tx_info->cookie,
231 ack_skb->data, ack_skb->len,
232 !tx_status->status, GFP_ATOMIC);
233 dev_kfree_skb_any(ack_skb);
234 }
235 }
225} 236}
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 4580942f6e80..e7d326f5b96e 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -374,7 +374,8 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
374 374
375 txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb); 375 txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
376 376
377 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) { 377 if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
378 tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
378 txpd->tx_token_id = tx_info->ack_frame_id; 379 txpd->tx_token_id = tx_info->ack_frame_id;
379 txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS; 380 txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
380 } 381 }