* [PATCH 0/5] mwifiex updates
@ 2014-11-25 14:43 Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 1/5] mwifiex: fix sparse warning Amitkumar Karwar
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Amitkumar Karwar @ 2014-11-25 14:43 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Cathy Luo, Avinash Patil, Marc Yang, Amitkumar Karwar
This patchset includes couple of fixes, delay work queue logic
removal for USB interface and Tx status support work.
Amitkumar Karwar (5):
mwifiex: fix sparse warning
mwifiex: fix scan problem on big endian platforms
mwifiex: skip delay main work logic for USB interface.
mwifiex: add Tx status support for EAPOL packets
mwifiex: add Tx status support for ACTION frames
drivers/net/wireless/mwifiex/cfg80211.c | 16 ++++++--
drivers/net/wireless/mwifiex/decl.h | 4 ++
drivers/net/wireless/mwifiex/fw.h | 17 ++++++--
drivers/net/wireless/mwifiex/init.c | 3 ++
drivers/net/wireless/mwifiex/main.c | 68 +++++++++++++++++++++++++++++---
drivers/net/wireless/mwifiex/main.h | 11 ++++++
drivers/net/wireless/mwifiex/scan.c | 2 +-
drivers/net/wireless/mwifiex/sta_event.c | 5 +++
drivers/net/wireless/mwifiex/sta_tx.c | 6 +++
drivers/net/wireless/mwifiex/txrx.c | 31 +++++++++++++++
drivers/net/wireless/mwifiex/uap_event.c | 4 ++
drivers/net/wireless/mwifiex/uap_txrx.c | 8 +++-
drivers/net/wireless/mwifiex/util.c | 2 +-
drivers/net/wireless/mwifiex/wmm.c | 10 +++++
14 files changed, 172 insertions(+), 15 deletions(-)
--
1.8.1.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] mwifiex: fix sparse warning
2014-11-25 14:43 [PATCH 0/5] mwifiex updates Amitkumar Karwar
@ 2014-11-25 14:43 ` Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 2/5] mwifiex: fix scan problem on big endian platforms Amitkumar Karwar
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Amitkumar Karwar @ 2014-11-25 14:43 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Cathy Luo, Avinash Patil, Marc Yang, Amitkumar Karwar
This patch fixes following sparse warnings:
drivers/net/wireless/mwifiex/util.c:152:19: warning: cast from restricted __le16
drivers/net/wireless/mwifiex/util.c:152:19: warning: restricted __le16 degrades to integer
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/mwifiex/util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index a113ef8..b1768fb 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -149,7 +149,7 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
u8 category, action_code;
struct ieee80211_hdr *ieee_hdr = (void *)payload;
- stype = (cpu_to_le16(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE);
+ stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE);
switch (stype) {
case IEEE80211_STYPE_ACTION:
--
1.8.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] mwifiex: fix scan problem on big endian platforms
2014-11-25 14:43 [PATCH 0/5] mwifiex updates Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 1/5] mwifiex: fix sparse warning Amitkumar Karwar
@ 2014-11-25 14:43 ` Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 3/5] mwifiex: skip delay main work logic for USB interface Amitkumar Karwar
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Amitkumar Karwar @ 2014-11-25 14:43 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Cathy Luo, Avinash Patil, Marc Yang, Amitkumar Karwar
This patch adds missing endian conversion for beacon size while
processing scan response.
Reported-by: Daniel Mosquera <daniel.mosquera@ctag.com>
Tested-by: Daniel Mosquera <daniel.mosquera@ctag.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/mwifiex/scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 3a17821..984a7a4 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1623,7 +1623,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
if (*bytes_left >= sizeof(beacon_size)) {
/* Extract & convert beacon size from command buffer */
- memcpy(&beacon_size, *bss_info, sizeof(beacon_size));
+ beacon_size = le16_to_cpu(*(__le16 *)(*bss_info));
*bytes_left -= sizeof(beacon_size);
*bss_info += sizeof(beacon_size);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] mwifiex: skip delay main work logic for USB interface.
2014-11-25 14:43 [PATCH 0/5] mwifiex updates Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 1/5] mwifiex: fix sparse warning Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 2/5] mwifiex: fix scan problem on big endian platforms Amitkumar Karwar
@ 2014-11-25 14:43 ` Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 4/5] mwifiex: add Tx status support for EAPOL packets Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 5/5] mwifiex: add Tx status support for ACTION frames Amitkumar Karwar
4 siblings, 0 replies; 6+ messages in thread
From: Amitkumar Karwar @ 2014-11-25 14:43 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Cathy Luo, Avinash Patil, Marc Yang, Amitkumar Karwar
We had introduced delay main work logic to avoid processing
interrupts when Rx pending packet count reaches high threshold.
interrupt processing is restarted later when packet count
reduces lower threashold. This helped to reduce unnecessary
overhead and improve throughput for SD and PCIe chipsets.
As there are no interrupts for USB, we will skip this logic for
USB chipsets.
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/mwifiex/main.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 0e50120..cf07279 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -149,7 +149,8 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
/* Check for Rx data */
while ((skb = skb_dequeue(&adapter->rx_data_q))) {
atomic_dec(&adapter->rx_pending);
- if (adapter->delay_main_work &&
+ if ((adapter->delay_main_work ||
+ adapter->iface_type == MWIFIEX_USB) &&
(atomic_read(&adapter->rx_pending) < LOW_RX_PENDING)) {
if (adapter->if_ops.submit_rem_rx_urbs)
adapter->if_ops.submit_rem_rx_urbs(adapter);
@@ -202,12 +203,15 @@ process_start:
(adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
break;
- /* If we process interrupts first, it would increase RX pending
- * even further. Avoid this by checking if rx_pending has
- * crossed high threshold and schedule rx work queue
- * and then process interrupts
+ /* For non-USB interfaces, If we process interrupts first, it
+ * would increase RX pending even further. Avoid this by
+ * checking if rx_pending has crossed high threshold and
+ * schedule rx work queue and then process interrupts.
+ * For USB interface, there are no interrupts. We already have
+ * HIGH_RX_PENDING check in usb.c
*/
- if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING) {
+ if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING &&
+ adapter->iface_type != MWIFIEX_USB) {
adapter->delay_main_work = true;
if (!adapter->rx_processing)
queue_work(adapter->rx_workqueue,
--
1.8.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] mwifiex: add Tx status support for EAPOL packets
2014-11-25 14:43 [PATCH 0/5] mwifiex updates Amitkumar Karwar
` (2 preceding siblings ...)
2014-11-25 14:43 ` [PATCH 3/5] mwifiex: skip delay main work logic for USB interface Amitkumar Karwar
@ 2014-11-25 14:43 ` Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 5/5] mwifiex: add Tx status support for ACTION frames Amitkumar Karwar
4 siblings, 0 replies; 6+ messages in thread
From: Amitkumar Karwar @ 2014-11-25 14:43 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Cathy Luo, Avinash Patil, Marc Yang, Amitkumar Karwar
Firmware notifies the driver through event if EAPOL data packet
has been acked or not. We will inform this status to userspace
listening on a socket.
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/mwifiex/cfg80211.c | 3 ++
drivers/net/wireless/mwifiex/decl.h | 2 ++
drivers/net/wireless/mwifiex/fw.h | 17 +++++++++--
drivers/net/wireless/mwifiex/init.c | 3 ++
drivers/net/wireless/mwifiex/main.c | 48 ++++++++++++++++++++++++++++++++
drivers/net/wireless/mwifiex/main.h | 7 +++++
drivers/net/wireless/mwifiex/sta_event.c | 5 ++++
drivers/net/wireless/mwifiex/sta_tx.c | 5 ++++
drivers/net/wireless/mwifiex/txrx.c | 20 +++++++++++++
drivers/net/wireless/mwifiex/uap_event.c | 4 +++
drivers/net/wireless/mwifiex/uap_txrx.c | 7 ++++-
drivers/net/wireless/mwifiex/wmm.c | 10 +++++++
12 files changed, 127 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 17f0ee0..68d5874 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2988,6 +2988,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
NL80211_FEATURE_INACTIVITY_TIMER |
NL80211_FEATURE_NEED_OBSS_SCAN;
+ if (adapter->fw_api_ver == MWIFIEX_FW_V15)
+ wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
+
/* Reserve space for mwifiex specific private data for BSS */
wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index fc0b1ed..9daa88a 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -76,6 +76,7 @@
#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
+#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
@@ -159,6 +160,7 @@ struct mwifiex_txinfo {
u8 bss_num;
u8 bss_type;
u32 pkt_len;
+ u8 ack_frame_id;
};
enum mwifiex_wmm_ac_e {
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index e095f37..fb5936e 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -494,6 +494,7 @@ enum P2P_MODES {
#define EVENT_TDLS_GENERIC_EVENT 0x00000052
#define EVENT_EXT_SCAN_REPORT 0x00000058
#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
+#define EVENT_TX_STATUS_REPORT 0x00000074
#define EVENT_ID_MASK 0xffff
#define BSS_NUM_MASK 0xf
@@ -542,6 +543,7 @@ struct mwifiex_ie_types_data {
#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08
#define MWIFIEX_TXPD_FLAGS_TDLS_PACKET 0x10
#define MWIFIEX_RXPD_FLAGS_TDLS_PACKET 0x01
+#define MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS 0x20
struct txpd {
u8 bss_type;
@@ -553,7 +555,9 @@ struct txpd {
u8 priority;
u8 flags;
u8 pkt_delay_2ms;
- u8 reserved1;
+ u8 reserved1[2];
+ u8 tx_token_id;
+ u8 reserved[2];
} __packed;
struct rxpd {
@@ -598,8 +602,9 @@ struct uap_txpd {
u8 priority;
u8 flags;
u8 pkt_delay_2ms;
- u8 reserved1;
- __le32 reserved2;
+ u8 reserved1[2];
+ u8 tx_token_id;
+ u8 reserved[2];
};
struct uap_rxpd {
@@ -1224,6 +1229,12 @@ struct mwifiex_event_scan_result {
u8 num_of_set;
} __packed;
+struct tx_status_event {
+ u8 packet_type;
+ u8 tx_token_id;
+ u8 status;
+} __packed;
+
#define MWIFIEX_USER_SCAN_CHAN_MAX 50
#define MWIFIEX_MAX_SSID_LIST_LENGTH 10
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index cc15ab8..520ad4a 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -473,6 +473,9 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
spin_lock_init(&priv->tx_ba_stream_tbl_lock);
spin_lock_init(&priv->rx_reorder_tbl_lock);
+
+ spin_lock_init(&priv->ack_status_lock);
+ idr_init(&priv->ack_status_frames);
}
return 0;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index cf07279..cf31d36 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -608,6 +608,44 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
return 0;
}
+static struct sk_buff *
+mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
+ struct sk_buff *skb, u8 flag)
+{
+ struct sk_buff *orig_skb = skb;
+ struct mwifiex_txinfo *tx_info, *orig_tx_info;
+
+ skb = skb_clone(skb, GFP_ATOMIC);
+ if (skb) {
+ unsigned long flags;
+ int id;
+
+ spin_lock_irqsave(&priv->ack_status_lock, flags);
+ id = idr_alloc(&priv->ack_status_frames, orig_skb,
+ 1, 0xff, GFP_ATOMIC);
+ spin_unlock_irqrestore(&priv->ack_status_lock, flags);
+
+ if (id >= 0) {
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ tx_info->ack_frame_id = id;
+ tx_info->flags |= flag;
+ orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb);
+ orig_tx_info->ack_frame_id = id;
+ orig_tx_info->flags |= flag;
+ } else if (skb_shared(skb)) {
+ kfree_skb(orig_skb);
+ } else {
+ kfree_skb(skb);
+ skb = orig_skb;
+ }
+ } else {
+ /* couldn't clone -- lose tx status ... */
+ skb = orig_skb;
+ }
+
+ return skb;
+}
+
/*
* CFG802.11 network device handler for data transmission.
*/
@@ -617,6 +655,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
struct sk_buff *new_skb;
struct mwifiex_txinfo *tx_info;
+ bool multicast;
dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
jiffies, priv->bss_type, priv->bss_num);
@@ -657,6 +696,15 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = skb->len;
+ multicast = is_multicast_ether_addr(skb->data);
+
+ if (unlikely(!multicast && skb->sk &&
+ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS &&
+ priv->adapter->fw_api_ver == MWIFIEX_FW_V15))
+ skb = mwifiex_clone_skb_for_tx_status(priv,
+ skb,
+ MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS);
+
/* Record the current time the packet was queued; used to
* determine the amount of time the packet was queued in
* the driver before it was sent to the firmware.
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 5a690d5..e19fc2f 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -34,6 +34,7 @@
#include <linux/firmware.h>
#include <linux/ctype.h>
#include <linux/of.h>
+#include <linux/idr.h>
#include "decl.h"
#include "ioctl.h"
@@ -578,6 +579,9 @@ struct mwifiex_private {
u8 check_tdls_tx;
struct timer_list auto_tdls_timer;
bool auto_tdls_timer_active;
+ struct idr ack_status_frames;
+ /* spin lock for ack status */
+ spinlock_t ack_status_lock;
};
enum mwifiex_ba_status {
@@ -1335,6 +1339,9 @@ void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac);
void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv);
void mwifiex_clean_auto_tdls(struct mwifiex_private *priv);
+void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
+ void *event_body);
+
#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 204ecc8..b8c171d 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -504,6 +504,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
break;
+ case EVENT_TX_STATUS_REPORT:
+ dev_dbg(adapter->dev, "event: TX_STATUS Report\n");
+ mwifiex_parse_tx_status_event(priv, adapter->event_body);
+ break;
+
default:
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
eventcause);
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index dab7b33..c69ecbc 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -77,6 +77,11 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
local_tx_pd->pkt_delay_2ms =
mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+ local_tx_pd->tx_token_id = tx_info->ack_frame_id;
+ local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
+ }
+
if (local_tx_pd->priority <
ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
/*
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index a5983fc..782bfd6 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -203,3 +203,23 @@ done:
}
EXPORT_SYMBOL_GPL(mwifiex_write_data_complete);
+void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
+ void *event_body)
+{
+ struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
+ struct sk_buff *ack_skb;
+ unsigned long flags;
+
+ if (!tx_status->tx_token_id)
+ return;
+
+ spin_lock_irqsave(&priv->ack_status_lock, flags);
+ ack_skb = idr_find(&priv->ack_status_frames, tx_status->tx_token_id);
+ if (ack_skb)
+ idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
+ spin_unlock_irqrestore(&priv->ack_status_lock, flags);
+
+ /* consumes ack_skb */
+ if (ack_skb)
+ skb_complete_wifi_ack(ack_skb, !tx_status->status);
+}
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 7c2b9766..38390cb 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -172,6 +172,10 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
return mwifiex_handle_event_ext_scan_report(priv,
adapter->event_skb->data);
break;
+ case EVENT_TX_STATUS_REPORT:
+ dev_dbg(adapter->dev, "event: TX_STATUS Report\n");
+ mwifiex_parse_tx_status_event(priv, adapter->event_body);
+ break;
default:
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
eventcause);
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index ec7309d..4580942 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -370,10 +370,15 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
txpd->bss_num = priv->bss_num;
txpd->bss_type = priv->bss_type;
txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - len));
-
txpd->priority = (u8)skb->priority;
+
txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+ txpd->tx_token_id = tx_info->ack_frame_id;
+ txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
+ }
+
if (txpd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
/*
* Set the priority specific tx_control field, setting of 0 will
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 94c98a8..dc1f2ad 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -523,6 +523,13 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
}
}
+static int mwifiex_free_ack_frame(int id, void *p, void *data)
+{
+ pr_warn("Have pending ack frames!\n");
+ kfree_skb(p);
+ return 0;
+}
+
/*
* This function cleans up the Tx and Rx queues.
*
@@ -558,6 +565,9 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
skb_queue_walk_safe(&priv->tdls_txq, skb, tmp)
mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+
+ idr_for_each(&priv->ack_status_frames, mwifiex_free_ack_frame, NULL);
+ idr_destroy(&priv->ack_status_frames);
}
/*
--
1.8.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] mwifiex: add Tx status support for ACTION frames
2014-11-25 14:43 [PATCH 0/5] mwifiex updates Amitkumar Karwar
` (3 preceding siblings ...)
2014-11-25 14:43 ` [PATCH 4/5] mwifiex: add Tx status support for EAPOL packets Amitkumar Karwar
@ 2014-11-25 14:43 ` Amitkumar Karwar
4 siblings, 0 replies; 6+ messages in thread
From: Amitkumar Karwar @ 2014-11-25 14:43 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Cathy Luo, Avinash Patil, Marc Yang, Amitkumar Karwar
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>
---
drivers/net/wireless/mwifiex/cfg80211.c | 13 ++++++++++---
drivers/net/wireless/mwifiex/decl.h | 2 ++
drivers/net/wireless/mwifiex/main.c | 10 +++++++---
drivers/net/wireless/mwifiex/main.h | 4 ++++
drivers/net/wireless/mwifiex/sta_tx.c | 3 ++-
drivers/net/wireless/mwifiex/txrx.c | 17 ++++++++++++++---
drivers/net/wireless/mwifiex/uap_txrx.c | 3 ++-
7 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 68d5874..f881044 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,
tx_info->pkt_len = pkt_len;
mwifiex_form_mgmt_frame(skb, buf, len);
- mwifiex_queue_tx_pkt(priv, skb);
-
*cookie = prandom_u32() | 1;
- cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC);
+
+ if (ieee80211_is_action(mgmt->frame_control))
+ skb = mwifiex_clone_skb_for_tx_status(priv,
+ skb,
+ MWIFIEX_BUF_FLAG_ACTION_TX_STATUS, cookie);
+ else
+ cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
+ GFP_ATOMIC);
+
+ mwifiex_queue_tx_pkt(priv, skb);
wiphy_dbg(wiphy, "info: management frame transmitted\n");
return 0;
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 9daa88a..2269acf 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -77,6 +77,7 @@
#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)
#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
+#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4)
#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
@@ -161,6 +162,7 @@ struct mwifiex_txinfo {
u8 bss_type;
u32 pkt_len;
u8 ack_frame_id;
+ u64 cookie;
};
enum mwifiex_wmm_ac_e {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index cf31d36..d4d2223 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)
return 0;
}
-static struct sk_buff *
+struct sk_buff *
mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
- struct sk_buff *skb, u8 flag)
+ struct sk_buff *skb, u8 flag, u64 *cookie)
{
struct sk_buff *orig_skb = skb;
struct mwifiex_txinfo *tx_info, *orig_tx_info;
@@ -632,6 +632,10 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb);
orig_tx_info->ack_frame_id = id;
orig_tx_info->flags |= flag;
+
+ if (flag == MWIFIEX_BUF_FLAG_ACTION_TX_STATUS && cookie)
+ orig_tx_info->cookie = *cookie;
+
} else if (skb_shared(skb)) {
kfree_skb(orig_skb);
} else {
@@ -703,7 +707,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv->adapter->fw_api_ver == MWIFIEX_FW_V15))
skb = mwifiex_clone_skb_for_tx_status(priv,
skb,
- MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS);
+ MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS, NULL);
/* Record the current time the packet was queued; used to
* 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 e19fc2f..bdba37b 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);
void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
void *event_body);
+struct sk_buff *
+mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
+ struct sk_buff *skb, u8 flag, u64 *cookie);
+
#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index c69ecbc..b896d73 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,
local_tx_pd->pkt_delay_2ms =
mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
- if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
+ tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
local_tx_pd->tx_token_id = tx_info->ack_frame_id;
local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
}
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 782bfd6..6ae1333 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,
struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
struct sk_buff *ack_skb;
unsigned long flags;
+ struct mwifiex_txinfo *tx_info;
if (!tx_status->tx_token_id)
return;
@@ -219,7 +220,17 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
spin_unlock_irqrestore(&priv->ack_status_lock, flags);
- /* consumes ack_skb */
- if (ack_skb)
- skb_complete_wifi_ack(ack_skb, !tx_status->status);
+ if (ack_skb) {
+ tx_info = MWIFIEX_SKB_TXCB(ack_skb);
+
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+ /* consumes ack_skb */
+ skb_complete_wifi_ack(ack_skb, !tx_status->status);
+ } else {
+ cfg80211_mgmt_tx_status(priv->wdev, tx_info->cookie,
+ ack_skb->data, ack_skb->len,
+ !tx_status->status, GFP_ATOMIC);
+ dev_kfree_skb_any(ack_skb);
+ }
+ }
}
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 4580942..e7d326f 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,
txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
- if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
+ tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
txpd->tx_token_id = tx_info->ack_frame_id;
txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-11-25 14:44 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-25 14:43 [PATCH 0/5] mwifiex updates Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 1/5] mwifiex: fix sparse warning Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 2/5] mwifiex: fix scan problem on big endian platforms Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 3/5] mwifiex: skip delay main work logic for USB interface Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 4/5] mwifiex: add Tx status support for EAPOL packets Amitkumar Karwar
2014-11-25 14:43 ` [PATCH 5/5] mwifiex: add Tx status support for ACTION frames Amitkumar Karwar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).