Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 808bbebc authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville
Browse files

mwifiex: add Tx status support for EAPOL packets



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: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 381e9fff
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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 {
+14 −3
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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;
+48 −0
Original line number Diff line number Diff line
@@ -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.
Loading