[PATCH 10/10] Fix Ad-Hoc mode

Kalle Valo kvalo at qca.qualcomm.com
Mon May 27 07:53:38 EDT 2013


Now I managed to create an Ad-Hoc network, join with iwlwifi and
ping the other node. It's not very reliable yet, though.

Signed-off-by: Kalle Valo <kvalo at qca.qualcomm.com>
---
 main.c |   40 ++++++++++++++++++++++++++++++++++++++++
 smd.c  |   16 +++++++++++-----
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/main.c b/main.c
index 8df9548..d6e0d75 100644
--- a/main.c
+++ b/main.c
@@ -224,6 +224,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 	struct wcn36xx *wcn = hw->priv;
 	struct sk_buff *skb = NULL;
 	u16 tim_off, tim_len;
+	enum wcn36xx_hal_link_state link_state;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x",
 		    vif, changed);
@@ -300,6 +301,14 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 			wcn36xx_smd_config_bss(wcn, wcn->iftype,
 					       wcn->addresses[0].addr, false);
 			wcn36xx_smd_send_beacon(wcn, skb, tim_off, 0);
+
+			if (vif->type == NL80211_IFTYPE_ADHOC)
+				link_state = WCN36XX_HAL_LINK_IBSS_STATE;
+			else
+				link_state = WCN36XX_HAL_LINK_AP_STATE;
+
+			wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr,
+						link_state);
 		} else {
 			/* FIXME: disable beaconing */
 		}
@@ -349,6 +358,35 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw,
 	return 0;
 }
 
+static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			   struct ieee80211_sta *sta)
+{
+ 	struct wcn36xx *wcn = hw->priv;
+
+ 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM",
+		    vif, sta->addr);
+
+	if (vif->type == NL80211_IFTYPE_ADHOC)
+		wcn36xx_smd_config_sta(wcn, wcn->addresses[0].addr,
+				       sta->addr);
+
+ 	return 0;
+}
+
+static int wcn36xx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			      struct ieee80211_sta *sta)
+{
+ 	struct wcn36xx *wcn = hw->priv;
+
+ 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM",
+		    vif, sta->addr);
+
+	if (vif->type == NL80211_IFTYPE_ADHOC)
+		wcn36xx_smd_delete_sta(wcn);
+
+	return 0;
+}
+
 static const struct ieee80211_ops wcn36xx_ops = {
 	.start 			= wcn36xx_start,
 	.stop	 		= wcn36xx_stop,
@@ -362,6 +400,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
 	.sw_scan_complete       = wcn36xx_sw_scan_complete,
 	.bss_info_changed 	= wcn36xx_bss_info_changed,
 	.set_rts_threshold	= wcn36xx_set_rts_threshold,
+	.sta_add		= wcn36xx_sta_add,
+	.sta_remove		= wcn36xx_sta_remove,
 };
 
 static struct ieee80211_hw *wcn36xx_alloc_hw(void)
diff --git a/smd.c b/smd.c
index 01bc567..99d40f4 100644
--- a/smd.c
+++ b/smd.c
@@ -459,7 +459,12 @@ int wcn36xx_smd_config_sta(struct wcn36xx *wcn, const u8 *bssid,
 	memcpy(&sta->bssid, bssid, ETH_ALEN);
 
 	sta->aid = wcn->aid;
-	sta->type = 0;
+
+	if (wcn->iftype == NL80211_IFTYPE_ADHOC)
+		sta->type = 1;
+	else
+		sta->type = 0;
+
 	sta->short_preamble_supported = 0;
 
 	memcpy(&sta->mac, sta_mac, ETH_ALEN);
@@ -678,8 +683,8 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, enum nl80211_iftype type,
 	} else if (type == NL80211_IFTYPE_ADHOC) {
 		bss->bss_type = WCN36XX_HAL_IBSS_MODE;
 
-		/* AP */
-		bss->oper_mode = 0;
+		/* STA */
+		bss->oper_mode = 1;
 	} else {
 		wcn36xx_warn("Unknown type for bss config: %d", type);
 	}
@@ -700,9 +705,10 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, enum nl80211_iftype type,
 	bss->ext_channel = 0;
 	bss->reserved = 0;
 
-	memcpy(&sta->bssid, &wcn->addresses[0], ETH_ALEN);
+	memcpy(&sta->bssid, bssid, ETH_ALEN);
+
 	sta->aid = wcn->aid;
-	sta->type = 1;
+	sta->type = 0;
 	sta->short_preamble_supported = 0;
 	memcpy(&sta->mac, &wcn->addresses[0], ETH_ALEN);
 	sta->listen_interval = 8;




More information about the wcn36xx mailing list