Search Linux Wireless

[PATCH 8/9] libertas_tf: updated with beacon code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Steve deRosier <steve@xxxxxxxxxxx>
---
 drivers/net/wireless/libertas_tf/cmd.c         |    2 +-
 drivers/net/wireless/libertas_tf/if_sdio.c     |    5 +-
 drivers/net/wireless/libertas_tf/libertas_tf.h |    6 ++
 drivers/net/wireless/libertas_tf/main.c        |   88 ++++++++++++++++++------
 4 files changed, 78 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c
index 738a2ff..8c15e35 100644
--- a/drivers/net/wireless/libertas_tf/cmd.c
+++ b/drivers/net/wireless/libertas_tf/cmd.c
@@ -354,7 +354,7 @@ void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
 {
 	struct cmd_ds_set_bssid cmd;
 	lbtf_deb_enter(LBTF_DEB_CMD);
-
+	lbtf_deb_cmd("Set BSSID: %pM a: %d", bssid, activate);
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	cmd.activate = activate ? 1 : 0;
 	if (activate)
diff --git a/drivers/net/wireless/libertas_tf/if_sdio.c b/drivers/net/wireless/libertas_tf/if_sdio.c
index 5074f8b..09c028f 100644
--- a/drivers/net/wireless/libertas_tf/if_sdio.c
+++ b/drivers/net/wireless/libertas_tf/if_sdio.c
@@ -303,8 +303,11 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
 			failure = (tmp & 0xff00) >> 8;
 			lbtf_deb_stats("Got feedback event. retry: %d, failure: %d", retrycnt, failure);
 			lbtf_send_tx_feedback(card->priv, retrycnt, failure);
-		} else if (event == LBTF_EVENT_BCN_SENT)
+		} else if (event == LBTF_EVENT_BCN_SENT) {
 			lbtf_bcn_sent(card->priv);
+		} else {
+			lbtf_deb_stats("UNKNOWN HOST EVENT: 0x%x", event);
+		}
 
 	ret = 0;
 
diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h
index c7588fd..db6dd7b 100644
--- a/drivers/net/wireless/libertas_tf/libertas_tf.h
+++ b/drivers/net/wireless/libertas_tf/libertas_tf.h
@@ -241,6 +241,8 @@ struct lbtf_private {
 
 	struct sk_buff *skb_to_tx;
 	struct sk_buff *tx_skb;
+	struct sk_buff *tx_skb_old;
+	struct sk_buff_head tx_skb_buf;
 
 	/** NIC Operation characteristics */
 	u16 mac_control;
@@ -267,6 +269,10 @@ struct lbtf_private {
 	u8 resp_idx;
 	u8 resp_buf[2][LBS_UPLD_SIZE];
 	u32 resp_len[2];
+	
+	/* beacon status info */
+	bool beacon_enable;
+	u16 beacon_int;
 
 };
 
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index cc2217c..6c4a1b6 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -272,6 +272,7 @@ static void lbtf_tx_work(struct work_struct *work)
 	if (priv->vif &&
 		 (priv->vif->type == NL80211_IFTYPE_AP) &&
 		 (!skb_queue_empty(&priv->bc_ps_buf))) {
+		lbtf_deb_tx("bc_ps_buf");
 		skb = skb_dequeue(&priv->bc_ps_buf);
 	}
 	else if (priv->skb_to_tx) {
@@ -306,15 +307,13 @@ static void lbtf_tx_work(struct work_struct *work)
 
 	lbtf_deb_hex(LBTF_DEB_TX, "TX Data ", skb->data, min_t(unsigned int, skb->len, 100));
 
-	WARN_ON(priv->tx_skb);
-
 	spin_lock_irq(&priv->driver_lock);
-	priv->tx_skb = skb;
+	skb_queue_tail(&priv->tx_skb_buf, skb);
 	err = priv->hw_host_to_card(priv, MVMS_DAT, skb->data, skb->len);
 	spin_unlock_irq(&priv->driver_lock);
 	if (err) {
 		dev_kfree_skb_any(skb);
-		priv->tx_skb = NULL;
+		skb_dequeue_tail(&priv->tx_skb_buf);
 		pr_err("TX error: %d", err);
 	}
 	lbtf_deb_tx("TX success");
@@ -417,8 +416,10 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw,
 	u8 null_addr[ETH_ALEN] = {0};
 	struct lbtf_private *priv = hw->priv;
 	lbtf_deb_enter(LBTF_DEB_MACOPS);
-	if (priv->vif != NULL)
+	if (priv->vif != NULL) {
+		lbtf_deb_macops("priv->vif != NULL");
 		return -EOPNOTSUPP;
+	}
 
 	priv->vif = vif;
 	switch (vif->type) {
@@ -431,6 +432,7 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw,
 		break;
 	default:
 		priv->vif = NULL;
+		lbtf_deb_macops("Unsupported interface mode: %d", vif->type);
 		return -EOPNOTSUPP;
 	}
 
@@ -548,7 +550,10 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
 	struct sk_buff *beacon;
 	lbtf_deb_enter(LBTF_DEB_MACOPS);
 
-	if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
+	lbtf_deb_macops("bss info changed: 0x%x", changes);
+	if (changes & (BSS_CHANGED_BEACON | 
+	               BSS_CHANGED_BEACON_INT | 
+	               BSS_CHANGED_BEACON_ENABLED)) {
 		switch (priv->vif->type) {
 		case NL80211_IFTYPE_AP:
 		case NL80211_IFTYPE_MESH_POINT:
@@ -556,7 +561,10 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
 			if (beacon) {
 				lbtf_beacon_set(priv, beacon);
 				kfree_skb(beacon);
-				lbtf_beacon_ctrl(priv, 1,
+				priv->beacon_enable = bss_conf->enable_beacon;
+				priv->beacon_int = bss_conf->beacon_int;
+				lbtf_set_bssid(priv, 1, bss_conf->bssid);
+				lbtf_beacon_ctrl(priv, bss_conf->enable_beacon,
 						 bss_conf->beacon_int);
 			}
 			break;
@@ -565,6 +573,21 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
 		}
 	}
 
+	if (changes & (BSS_CHANGED_BEACON_INT | 
+	               BSS_CHANGED_BEACON_ENABLED)) {
+		switch (priv->vif->type) {
+		case NL80211_IFTYPE_AP:
+		case NL80211_IFTYPE_MESH_POINT:
+				priv->beacon_enable = bss_conf->enable_beacon;
+				priv->beacon_int = bss_conf->beacon_int;
+				lbtf_beacon_ctrl(priv, bss_conf->enable_beacon,
+						 bss_conf->beacon_int);
+			break;
+		default:
+			break;
+		}
+	}
+
 	if (changes & BSS_CHANGED_BSSID) {
 		bool activate = !is_zero_ether_addr(bss_conf->bssid);
 		lbtf_set_bssid(priv, activate, bss_conf->bssid);
@@ -688,6 +711,7 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev, u8 mac_addr
 	priv->hw = hw;
 	priv->card = card;
 	priv->tx_skb = NULL;
+	priv->tx_skb_old = NULL;
 
 	hw->queues = 1;
 	hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
@@ -701,8 +725,11 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev, u8 mac_addr
 	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
-		BIT(NL80211_IFTYPE_ADHOC);
+		BIT(NL80211_IFTYPE_ADHOC) |
+		BIT(NL80211_IFTYPE_AP) |
+		BIT(NL80211_IFTYPE_MESH_POINT);
 	skb_queue_head_init(&priv->bc_ps_buf);
+	skb_queue_head_init(&priv->tx_skb_buf);
 
 	SET_IEEE80211_DEV(hw, dmdev);
 
@@ -758,15 +785,20 @@ EXPORT_SYMBOL_GPL(lbtf_remove_card);
 void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail)
 {
 	struct ieee80211_tx_info *info;
+	struct sk_buff *skb = NULL;
 	lbtf_deb_enter(LBTF_DEB_MAIN);
 
-	if(priv->tx_skb == 0) {
-		lbtf_deb_stats("tx_skb is null");
+	if (!skb_queue_empty(&priv->tx_skb_buf)) {
+		skb = skb_dequeue(&priv->tx_skb_buf);
+	}
+	
+	if(skb == 0) {
+		lbtf_deb_stats("skb is null");
 	} else {
 
-		lbtf_deb_stats("tx_skb is ok");
+		lbtf_deb_stats("skb is ok");
 
-		info = IEEE80211_SKB_CB(priv->tx_skb);
+		info = IEEE80211_SKB_CB(skb);
 		ieee80211_tx_info_clear_status(info);
 		/*
 		 * Commented out, otherwise we never go beyond 1Mbit/s using mac80211
@@ -777,15 +809,14 @@ void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail)
 		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail) {
 			info->flags |= IEEE80211_TX_STAT_ACK;
 		}
-		skb_pull(priv->tx_skb, sizeof(struct txpd));
-		ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+		skb_pull(skb, sizeof(struct txpd));
+		ieee80211_tx_status_irqsafe(priv->hw, skb);
 	}
 
-		priv->tx_skb = NULL;
-		if (!priv->skb_to_tx && skb_queue_empty(&priv->bc_ps_buf))
-			ieee80211_wake_queues(priv->hw);
-		else
-			queue_work(lbtf_wq, &priv->tx_work);
+	if (!priv->skb_to_tx && skb_queue_empty(&priv->bc_ps_buf))
+		ieee80211_wake_queues(priv->hw);
+	else
+		queue_work(lbtf_wq, &priv->tx_work);
 
 	lbtf_deb_leave(LBTF_DEB_MAIN);
 }
@@ -810,7 +841,7 @@ void lbtf_host_to_card_done(struct lbtf_private *priv )
 		lbtf_deb_main("Got done on command.");
 	}
 
-	lbtf_deb_leave(LBTF_DEB_THREAD);
+	lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 EXPORT_SYMBOL_GPL(lbtf_host_to_card_done);
 
@@ -818,6 +849,18 @@ void lbtf_bcn_sent(struct lbtf_private *priv)
 {
 	struct sk_buff *skb = NULL;
 
+	lbtf_deb_enter(LBTF_DEB_MAIN);
+
+	if (!priv) {
+		lbtf_deb_main("got bcn sent with priv == NULL");
+		return;
+	}
+
+	if (!priv->vif) {
+		lbtf_deb_main("got bcn sent with vif == NULL");
+		return;
+	}
+
 	if (priv->vif->type != NL80211_IFTYPE_AP)
 		return;
 
@@ -837,9 +880,12 @@ void lbtf_bcn_sent(struct lbtf_private *priv)
 	skb = ieee80211_beacon_get(priv->hw, priv->vif);
 
 	if (skb) {
-		lbtf_beacon_set(priv, skb);
+ 		lbtf_beacon_set(priv, skb);
 		kfree_skb(skb);
+ 		lbtf_beacon_ctrl(priv, priv->beacon_enable, priv->beacon_int);
 	}
+
+	lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 EXPORT_SYMBOL_GPL(lbtf_bcn_sent);
 
-- 
1.7.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux