summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorStone Piao <piaoyun@marvell.com>2012-09-26 05:23:35 +0200
committerJohn W. Linville <linville@tuxdriver.com>2012-09-28 19:54:04 +0200
commit2dbaf751b1dec3a603130a475f94cc4d3f404362 (patch)
treee308825a97d632f4f5b6a7f3d7cad03bdf8f818c /drivers/net
parentmwifiex: implement cfg80211 mgmt_frame_register handler (diff)
downloadlinux-2dbaf751b1dec3a603130a475f94cc4d3f404362.tar.xz
linux-2dbaf751b1dec3a603130a475f94cc4d3f404362.zip
mwifiex: report received management frames to cfg80211
Process the management frames received from firmware and report them to cfg80211. Signed-off-by: Stone Piao <piaoyun@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: Kevin Gan <ganhy@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/mwifiex/fw.h1
-rw-r--r--drivers/net/wireless/mwifiex/init.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.h4
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c6
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c6
-rw-r--r--drivers/net/wireless/mwifiex/util.c40
6 files changed, 58 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 41b304a33a07..b587ea3feffa 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -94,6 +94,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
};
#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF)))
+#define CAL_RSSI(SNR, NF) ((s16)((s16)(SNR)+(s16)(NF)))
#define UAP_BSS_PARAMS_I 0
#define UAP_CUSTOM_IE_I 1
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index b2ba262f8a13..105a5c5d7d5d 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -214,6 +214,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
priv->wps_ie = NULL;
priv->wps_ie_len = 0;
priv->ap_11n_enabled = 0;
+ priv->mgmt_rx_freq = 2437;
priv->scan_block = false;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 6e0806244b82..ec5794ef4366 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -497,6 +497,7 @@ struct mwifiex_private {
struct timer_list scan_delay_timer;
u8 ap_11n_enabled;
u32 mgmt_frame_mask;
+ u32 mgmt_rx_freq;
};
enum mwifiex_ba_status {
@@ -741,6 +742,9 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
+int mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb);
+
int mwifiex_process_event(struct mwifiex_adapter *adapter);
int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index d91d5c08c73a..07d32b73783e 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -174,6 +174,12 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
dev_err(adapter->dev, "Rx of A-MSDU failed");
}
return 0;
+ } else if (rx_pkt_type == PKT_TYPE_MGMT) {
+ ret = mwifiex_process_mgmt_packet(adapter, skb);
+ if (ret)
+ dev_err(adapter->dev, "Rx of mgmt packet failed");
+ dev_kfree_skb_any(skb);
+ return ret;
}
/*
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index df17d08715fe..012c1433d126 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -217,6 +217,12 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter,
}
return 0;
+ } else if (rx_pkt_type == PKT_TYPE_MGMT) {
+ ret = mwifiex_process_mgmt_packet(adapter, skb);
+ if (ret)
+ dev_err(adapter->dev, "Rx of mgmt packet failed");
+ dev_kfree_skb_any(skb);
+ return ret;
}
memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 2864c74bdb6f..e1dc3e41c65d 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -142,6 +142,46 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
}
/*
+ * This function processes the received management packet and send it
+ * to the kernel.
+ */
+int
+mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter,
+ struct sk_buff *skb)
+{
+ struct rxpd *rx_pd;
+ struct mwifiex_private *priv;
+ u16 pkt_len;
+
+ if (!skb)
+ return -1;
+
+ rx_pd = (struct rxpd *)skb->data;
+ priv = mwifiex_get_priv_by_id(adapter, rx_pd->bss_num, rx_pd->bss_type);
+ if (!priv)
+ return -1;
+
+ skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
+ skb_pull(skb, sizeof(pkt_len));
+
+ pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
+
+ /* Remove address4 */
+ memmove(skb->data + sizeof(struct ieee80211_hdr_3addr),
+ skb->data + sizeof(struct ieee80211_hdr),
+ pkt_len - sizeof(struct ieee80211_hdr));
+
+ pkt_len -= ETH_ALEN + sizeof(pkt_len);
+ rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
+
+ cfg80211_rx_mgmt(priv->wdev, priv->mgmt_rx_freq,
+ CAL_RSSI(rx_pd->snr, rx_pd->nf),
+ skb->data, pkt_len, GFP_ATOMIC);
+
+ return 0;
+}
+
+/*
* This function processes the received packet before sending it to the
* kernel.
*