[PATCH] Send probe as unicast in joining state

Eugene Krasnikov k.eugene.e at gmail.com
Tue May 28 10:42:10 EDT 2013


While joining mac will try to send direct probe in case mac
never received any probes from AP. But mac instead of sending
unicast probe will send broadcast probe because some APs do
not answer to direct packet in unassociated state. And HW
cannot send broadcast packets in joining state so trick it
like we are sending unicast probe instead of broadcast.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 main.c    | 12 ++++++++++++
 wcn36xx.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/main.c b/main.c
index 6804482..a1fa705 100644
--- a/main.c
+++ b/main.c
@@ -179,6 +179,7 @@ static void wcn36xx_tx(struct ieee80211_hw *hw,
 	struct ieee80211_mgmt *mgmt;
 	bool high, bcast;
 	u32 header_len = 0;
+	struct wcn36xx *wcn = hw->priv;
 
 	mgmt = (struct ieee80211_mgmt *)skb->data;
 
@@ -188,6 +189,13 @@ static void wcn36xx_tx(struct ieee80211_hw *hw,
 	bcast = is_broadcast_ether_addr(mgmt->da) ||
 		is_multicast_ether_addr(mgmt->da);
 
+	/*
+	 * In joining state trick hardware that probe is sent as unicast even
+	 * if address is broadcast.
+	 */
+	if (wcn->is_joining && ieee80211_is_probe_req(mgmt->frame_control)) {
+		bcast = false;
+	}
 	wcn36xx_dbg(WCN36XX_DBG_TX,
 		    "tx skb %p len %d fc %04x sn %d %s %s",
 		    skb, skb->len, __le16_to_cpu(mgmt->frame_control),
@@ -199,6 +207,7 @@ static void wcn36xx_tx(struct ieee80211_hw *hw,
 	header_len = ieee80211_is_data_qos(mgmt->frame_control) ?
 		sizeof(struct ieee80211_qos_hdr) :
 		sizeof(struct ieee80211_hdr_3addr);
+		wcn->is_joining = false;
 	wcn36xx_dxe_tx(hw->priv, skb, bcast, high, header_len);
 }
 
@@ -299,6 +308,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 
 		if (vif->type == NL80211_IFTYPE_STATION &&
 		    !is_zero_ether_addr(bss_conf->bssid)) {
+			wcn->is_joining = true;
 			wcn36xx_smd_join(wcn, bss_conf->bssid, vif->addr, wcn->ch);
 			wcn36xx_smd_config_bss(wcn, NL80211_IFTYPE_STATION,
 					       bss_conf->bssid, false);
@@ -316,6 +326,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 	}
 
 	if (changed & BSS_CHANGED_ASSOC) {
+		wcn->is_joining = false;
 		if(bss_conf->assoc) {
 			wcn36xx_dbg(WCN36XX_DBG_MAC,
 				    "mac assoc bss %pM vif %pM AID=%d",
@@ -777,6 +788,7 @@ static int __init wcn36xx_init(void)
 
 	wcn->aid = 0;
 	wcn->current_vif = NULL;
+	wcn->is_joining = false;
 	wcn->hw->wiphy->n_addresses = ARRAY_SIZE(wcn->addresses);
 	wcn->hw->wiphy->addresses = wcn->addresses;
 
diff --git a/wcn36xx.h b/wcn36xx.h
index f9788e5..efebd85 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -137,6 +137,7 @@ struct wcn36xx {
 
 	//Scanning
 	int                     is_scanning;
+	bool			is_joining;
 
 	// DXE chanels
 	struct wcn36xx_dxe_ch 	dxe_tx_l_ch;	// TX low channel
-- 
1.7.11.3




More information about the wcn36xx mailing list